Page 221

4 Estructuras de datos: memoria din´amica

CC 2003, 2008 Andr´ es Marzal e Isabel Gracia

Es decir, se reserva suficiente memoria para albergar 5 enteros. Como puedes ver, las l´ıneas 11–12 tratan a a como si fuera un vector de enteros cualquiera. Una vez has reservado memoria para un vector din´amico, no hay diferencia alguna entre ´el y un vector est´atico desde el punto de vista pr´actico. Ambos pueden indexarse (l´ınea 12) o pasarse como argumento a funciones que admiten un vector del mismo tipo base. Aritm´ etica de punteros Una curiosidad: el acceso indexado a[0] es equivalente a *a. En general, a[i] es equivalente a *(a+i), es decir, ambas son formas de expresar el concepto ((accede al contenido de la direcci´ on a con un desplazamiento de i veces el tama˜ no del tipo base)). La sentencia de asignaci´ on a[i] = i podr´ıa haberse escrito como *(a+i) = i. En C es posible sumar o restar un valor entero a un puntero. El entero se interpreta como un desplazamiento dado en unidades ((tama˜ no del tipo base)) (en el ejemplo, 4 bytes, que es el tama˜ no de un int). Es lo que se conoce por aritm´etica de punteros. La aritm´etica de punteros es un punto fuerte de C, aunque tambi´en tiene sus detractores: resulta sencillo provocar accesos incorrectos a memoria si se usa mal.

Finalmente, la l´ınea 13 del programa libera la memoria reservada y la l´ınea 14 guarda en a un valor especial: NULL. La funci´ on free tiene un prototipo similar a ´este: stdlib.h ... void free(void * puntero); ...

Como ves, free recibe un puntero a cualquier tipo de datos: la direcci´on de memoria en la que empieza un bloque previamente obtenido con una llamada a malloc. Lo que hace free es liberar ese bloque de memoria, es decir, considerar que pasa a estar disponible para otras posibles llamadas a malloc. Es como cerrar un fichero: si no necesito un recurso, lo libero para que otros lo puedan aprovechar.2 Puedes aprovechar as´ı la memoria de forma ´optima. Recuerda: tu programa debe efectuar una llamada a free por cada llamada a malloc. Es muy importante. Conviene que despu´es de hacer free asignes al puntero el valor NULL, especialmente si la variable sigue ((viva)) durante bastante tiempo. NULL es una constante definida en stdlib.h. Si un puntero vale NULL, se entiende que no apunta a un bloque de memoria. Gr´aficamente, un puntero que apunta a NULL se representa as´ı: a

Liberar memoria no cambia el valor del puntero La llamada a free libera la memoria apuntada por un puntero, pero no modifica el valor de la variable que se le pasa. Imagina que un bloque de memoria de 10 enteros que empieza en la direcci´ on 1000 es apuntado por una variable a de tipo int *, es decir, imagina que a vale 1000. Cuando ejecutamos free(a), ese bloque se libera y pasa a estar disponible para eventuales llamadas a malloc, pero ¡a sigue valiendo 1000! ¿Por qu´e? Porque a se ha pasado a free por valor, no por referencia, as´ı que free no tiene forma de modificar el valor de a. Es recomendable que asignes a a el valor NULL despu´es de una llamada a free, pues as´ı haces expl´ıcito que la variable a no apunta a nada. Recuerda, pues, que es responsabilidad tuya y que conviene hacerlo: asigna expl´ıcitamente el valor NULL a todo puntero que no apunte a memoria reservada.

La funci´ on malloc puede fallar por diferentes motivos. Podemos saber cu´ando ha fallado porque malloc lo notifica devolviendo el valor NULL. Imagina que solicitas 2 megabytes de memoria en un ordenador que s´ olo dispone de 1 megabyte. En tal caso, la funci´on malloc devolver´a el valor NULL para indicar que no pudo efectuar la reserva de memoria solicitada. 2 Y, como en el caso de un fichero, si no lo liberas t´ u expl´ıcitamente, se libera autom´ aticamente al finalizar la ejecuci´ on del programa. A´ un as´ı, te exigimos disciplina: obl´ıgate a liberarlo t´ u mismo tan pronto dejes de necesitarlo.

Introducci´ on a la Programaci´ on con C

215

Profile for esLibre.com

Introducción a la programación con c  

Introducción a la programación con c  

Advertisement