Curso de C++ (Página 13d)

pagina013c Principal pagina014a

CAPITULO 13d Tipos de variables IV: Punteros 1

Variables dinámicas:

Donde mayor potencia desarrollan los punteros es cuando se unen al concepto de memoria dinámica.

Cuando se ejecuta un programa, el sistema operativo reserva una zona de memoria para el código o instrucciones del programa y otra para las variables que se usan durante la ejecución. A menudo estas zonas son la misma zona, es lo que se llama memoria local. También hay otras zonas de memoria, como la pila, que se usa, entre otras cosas, para intercambiar datos entre funciones. El resto, la memoria que no se usa por ningún programa es lo que se conoce como "heap" o montón. Cuando nuestro programa use memoria dinámica, normalmente usará memoria del montón, y no se llama así porque sea de peor calidad, sino porque suele haber realmente un montón de memoria de este tipo.

C++ dispone de dos operadores para acceder a la memoria dinámica, son "new" y "delete". En C estas acciones se realizan mediante funciones de la librería estándar "mem.h".

Hay una regla de oro cuando se usa memoria dinámica, toda la memoria que se reserve durante el programa hay que liberarla antes de salir del programa. No seguir esta regla es una actitud muy irresponsable, y en la mayor parte de los casos tiene consecuencias desastrosas. No os fieis de lo que diga el compilador, de que estas variables se liberan solas al terminar el programa, no siempre es verdad.

Veremos con mayor profundidad los operadores "new" y "delete" en el siguiente capítulo, por ahora veremos un ejemplo:

#include <iostream.h>
 
int main() { 
   int *a; 
   char *b; 
   float *c; 
   struct stPunto { 
      float x,y; 
   } *d;
 
   a = new int; 
   b = new char; 
   c = new float; 
   d = new stPunto;
 
   *a = 10; 
   *b = 'a'; 
   *c = 10.32; 
   d->x = 12; d->y = 15;
 
   cout << "a = " << *a << endl; 
   cout << "b = " << *b << endl; 
   cout << "c = " << *c << endl; 
   cout << "d = (" << d->x << ", " << d->y << ")" << endl;
 
   delete a; 
   delete b; 
   delete c; 
   delete d; 

   return 0; 
} 

Y mucho cuidado: si pierdes un puntero a una variable reservada dinámicamente, no podrás liberarla.

Ejemplo:

int main() {
   int *a;
 
   a = new int; // variable dinámica
   *a = 10;
   a = new int; // nueva variable dinámica, se pierde la anterior
   *a = 20;
   delete a;  // sólo liberamos la última reservada
   return 0;
}

En este ejemplo vemos cómo es imposible liberar la primera reserva de memoria dinámica. Si no la necesitábamos habría que liberarla antes de reservarla otra vez, y si la necesitamos, hay que guardar su dirección, por ejemplo con otro puntero.

Ejercicios:

1. Escribir un programa con una función que calcule la longitud de una cadena de caracteres. El nombre de la función será LongitudCadena, debe devolver un "int", y como parámetro de entrada debe tener un puntero a "char". En "main" probar con distintos tipos de cadenas: arrays y punteros.

2. Escribir un programa con una función que busque un carácter determinado en una cadena. El nombre de la función será BuscaCaracter, debe devolver un "int" con la posición en que fue encontrado el carácter, si no se encontró volverá con -1. Los parámetros de entrada serán una cadena y un carácter. En la función "main" probar con distintas cadenas y caracteres.


pagina013c Principal pagina014a