Universidad Carlos III de Madrid

Grado en Ing. Telemática/Sist. Audiovisuales/Sist. de Comunicaciones

Arquitectura de Sistemas

Septiembre 2012 - Enero 2013

3. El heap y la memoria dinámica

La memoria dinámica que se almacena en el heap es aquella que se utiliza para almacenar datos que se crean en el medio de la ejecución de un programa. En general, este tipo de datos puede llegar a ser casi la totalidad de los datos de un programa. Por ejemplo, supóngase un programa que abre un fichero y lee una colección de palabras. ¿Cuántas palabras y de qué tamaño hay en el fichero? Hasta que no se procese el fichero en su totalidad, no es posible saberlo.

La manipulación de memoria en C se hace con un mecanismo muy simple, pero a la vez muy propenso a errores. Los dos tipos de operaciones son la petición y liberación de memoria. El ciclo es sencillo, cuando se precisa almacenar un nuevo dato, se solicita tanta memoria en bytes como sea necesaria, y una vez que ese dato ya no se necesita la memoria se devuelve para poder ser reutilizada. Este esquema se conoce como gestión explícita de memoria pues requiere ejecutar una operación para pedir la memoria y otra para liberarla.

Las cuatro operaciones principales para gestionar memoria en C son:

  • void *malloc(size_t size). Es la función para reservar tantos bytes consecutivos de memoria como indica su único parámetro. Devuelve la dirección de memoria de la porción reservada. La memoria no se inicializa a ningún valor.

  • void *calloc(size_t nmemb, size_t size). Reserva espacio para tantos elementos como indica su primer parámetro nmemb, y cada uno de ellos con un tamaño en bytes como indica el segundo. En otras palabras, reserva nmemb * size bytes consecutivos en memoria. Al igual que la función anterior devuelve la dirección de memoria al comienzo del bloque reservado. Esta función inicializa todos los bytes de la zona reservada al valor cero.

  • void free(void *ptr). Función que dado un puntero, libera el espacio previamente reservado. El puntero que recibe como parámetro esta función tiene que ser el que se ha obtenido con una llamada de reserva de memoria. No es necesario incluir el tamaño. Una vez que se ejecuta esta llamada, los datos en esa porción de memoria se consideran basura, y por tanto pueden ser reutilizados por el sistema.

  • void *realloc(void *ptr, size_t size). Función para redimensionar una porción de memoria previamente reservada a la que apunta el primer parámetro al tamaño dado como segundo parámetro. La función devuelve la dirección de memoria de esta nueva porción redimensionada, que no tiene por qué ser necesariamente igual al que se ha pasado como parámetro. Los datos se conservan intactos en tantos bytes como el mínimo entre el tamaño antiguo y el nuevo.

Responde a las siguientes preguntas para ver si has entendido lo que se explica en este documento:

  1. Si tenemos que reservar una nueva porción de memoria dinámica e inicializarla a 0, utilizaremos

    • malloc

    • calloc

    • realloc

    • free

  2. En un programa desde el inicio hasta su finalización, debemos realizar tantas invocaciones a "free" como la suma de invocaciones de malloc y calloc

    • Verdadero

    • Falso