Memoria dinámica - Universidad de Costa Rica

Anuncio
Universidad de Costa Rica | Escuela de Ingeniería Eléctrica
IE-0117 Programación Bajo Plataformas Abiertas
Memoria dinámica
1.
Asignación de memoria en un programa
Existen dos formas básicas de asignar memoria para un programa. La asignación de memoria estática define la
cantidad de memoria que se utilizará en tiempo de compilación y no durante la ejecución del programa. Este es el tipo
de asignación estándar usado en C cuando se crean variables y arreglos regulares.
La asignación de memoria estática es muy eficiente y consume pocos recursos. Sin embargo, es poco flexible, sobretodo cuando un programa debe manejar datos de tamaño variable.
Por otro lado, la asignación de memoria dinámica permite que un programa pueda reservar nueva memoria, de
tamaño variable, en cualquier momento de la ejecución de un programa. El programa debe hacer una solicitud al sistema
operativo. Si hay suficiente memoria disponible el sistema operativo asignará la memoria y le retornará al programa un
puntero que hace referencia al inicio del sector reservado.
2.
Solicitud de nueva memoria
La solicitud de nueva memoria se hace usando las funciones malloc() o calloc(). Ambas funciones difieren únicamente en la forma en que se especifica la cantidad de memoria.
malloc() recibe como argumento un número entero que indica la cantidad de bytes que se desea reservar. calloc()
recibe dos argumentos: la cantidad de elementos que se almacenaran en el sector de memoria solicitado y el tamaño de
cada uno de ellos.
Ambas funciones retornan un puntero genérico (void *) que apunta al inicio del sector de memoria reservado, o bien
el puntero NULL en caso de que no se pueda hacer la asignación.
int *a, *b;
a = (int *)malloc(20 * sizeof(int));
b = (int *)calloc(20, sizeof(int));
En el ejemplo se asignan dos porciones de memoria del mismo tamaño, cada una con capacidad para almacenar
20 números enteros. Nótese como es necesario hacer un casting para convertir el puntero genérico retornado por las
funciones al tipo correcto.
Debido a que se utiliza un puntero para manejar la porción de memoria dinámica, puede usarse aritmética de punteros,
o bien el operador [] para acceder a cada posición:
int i;
for(i = 0; i < 20; i++) {
a[i] = i;
}
1
IE-0117 Programación Bajo Plataformas Abiertas
3.
Memoria dinámica
Cambio del tamaño de un sector de memoria dinámica
Es posible cambiar el tamaño de un sector de memoria reservado dinamicamente en cualquier momento, usando la
función realloc():
a = (int *)realloc((void *)a, 50 * sizeof(int));
En el ejemplo se cambia el tamaño del área de memoria a la que hace referencia a para que pueda almacenar 50
enteros.
Si se el tamaño original es menor que el nuevo tamaño, simplemente se agregará más espacio al final. Si el nuevo
tamaño es menor, se truncará el sector de memoria y se perderán los últimos elementos.
El cambio de tamaño de la memoria puede ser ineficiente en ocasiones, debido a que no siempre hay sufiente memoria
contigua y es necesario copiar los datos a otras posiciones con más espacio. Por esta razón debe evitarse efectuar esta
operación.
4.
Liberación de memoria
Algunos lenguajes de alto nivel como Java y Python utilizan memoria dinámica para almacenar la mayoría de las
variables de un programa. Por esta razón, estos lenguajes implementan componentes, conocidos generalmente como
recolectores de basura que liberan automáticamente la memoria cuando no se necesita más.
El lenguaje C no cuenta con herramientas de este tipo, por lo que es necesario liberar la memoria manualmente. Es de
suma importancia llevar a cabo esta tarea en el momento adecuado para evitar fugas de memoria que puedan afectar
el desempeño de la aplicación y del sistema en general.
Para liberar memoria debe usarse la función free():
free(a);
2
Descargar