Hasta ahora hemos visto que cada vez que queremos usar una variable debemos reservarle un lugar de la memoria al comenzar el programa. Debemos indicar cuánta memoria vamos a usar. Pero hay ocasiones en que esto no es bueno, hay veces en las que no sabemos cuánta memoria vamos a necesitar. Por ejemplo si hacemos un editor de texto no podemos saber de antemano cuál va a ser la longitud del texto.
Por eso a veces es necesario poder reservar memoria según se va necesitando. Además de esta forma nuestros programas aprovecharán mejor la memoria del ordenador en el que se ejecuten, usando sólo lo necesario.
La asignación de memoria es la base de lo que veremos en capítulos posteriores, especialmente los capítulos de listas enlazadas. En éstos capítulos es donde se verá la verdadera utilidad de la asignación dinámica.
Existen varias funciones para la asignación dinámica de la memoria, pero las dos funciones básicas son malloc y free.
La función malloc (Memory allocate - asignar memoria) reservar una parte de la memoria y devuelve la dirección del comienzo de esa parte. Esta dirección podemos almacenarla en un puntero y así podemos acceder a la memoria reservada. La función malloc tiene el siguiente formato:
puntero = (tipo_de_variable *) malloc( número de bytes a reservar );
Una vez reservada la memoria y guardada su dirección en un puntero podemos usar ese puntero como hemos visto hasta ahora.
Si no había suficiente memoria libre malloc devolverá el valor NULL. El puntero por tanto apuntará a NULL. Es muy importante comprobar siempre si se ha podido reservar memoria o no comprobando el valor de puntero:
if (puntero)
se cumple si hay memoria suficiente, en caso contrario el falso.
Cuando ya no necesitemos más el espacio reservado debemos liberarlo, es decir, indicar al ordenador que puede destinarlo a otros fines. Si no liberamos el espacio que ya no necesitamos corremos el peligro de agotar la memoria del ordenador. Para ello usamos la función free, que funciona de la siguiente manera:
free( puntero );
Donde puntero es un puntero que apunta al comienzo del bloque que habíamos reservado. Es muy importante no perder la dirección del comienzo del bloque, pues de otra forma no podremos liberarlo.
Vamos a ver un sencillo ejemplo del manejo de malloc
y free
:
#include <stdio.h> int main() { int bytes; char *texto; printf("Cuantos bytes quieres reservar: "); scanf("%i",&bytes); texto = (char *) malloc(bytes); /* Comprobamos si ha tenido éxito la operación */ if (texto) { printf("Memoria reservada: %i bytes = %i kbytes = %i Mbytes\n", bytes, bytes/1024, bytes/(1024*1024)); printf("El bloque comienza en la dirección: %p\n", texto); /* Ahora liberamos la memoria */ free( texto ); } else printf("No se ha podido reservar memoria\n"); }
En este ejemplo se pregunta cuánta memoria se quiere reservar, si se consigue se indica cuánta memoria se ha reservado y dónde comienza el bloque. Si no se consigue se indica meniante el mensaje: "No se ha podido reservar memoria".
Probemos este ejemplo reservando 1000 bytes:
Cuantos bytes quieres reservar: 1000 Memoria reservada: 1000 bytes = 0 kbytes = 0 Mbytes El bloque comienza en la dirección: 90868
Pruébalo unas cuantas veces incrementando el tamaño de la memoria que quieres reservar. Si tienes 32Mbytes de memoria RAM teclea lo siguiente:
Cuantos bytes quieres reservar: 32000000 No se ha podido reservar memoria
Malloc no ha podido reservar tanta memoria y devuelve (null) por lo que se nos avisa de que la operación no se ha podido realizar.
Ejercicio :
Solución:
© Gorka Urrutia