Tema 13: Asignación Dinámica de memoria Indice 1. Introducción 2. Funciones para la asignación dinámica de memoria 3. Vectores y cadenas dinámicos. 1 1. Introducción • Estructuras Estáticas: Su tamaño no varía en tiempo de ejecución • Vectores. • Tablas • Registros • Estructuras Dinámicas Su tamaño puede variar en tiempo de ejecución • • • • Vectores y cadenas dinámicas Listas Pilas Colas Introducción • La asignación dinámica de memoria consiste en reservar sólo la memoria necesaria en cada momento (por eso el tamaño de las estructuras variará) • No será necesario establecer un límite máximo para la estructura, ya que irá creciendo o decreciendo a medida que se vaya necesitando. • Las estructuras dinámicas se apoyan en el uso de punteros. 2 Introducción Al tratar con memoria dinámica tendremos que: 1. 2. 3. Reservar la memoria que necesitemos. Hacer uso de la Estructura de Datos Dinámica (cuyo tamaño podrá ir variando) Liberar la memoria reservada: Cuando no necesitemos más ese espacio de memoria hay que indicarle al S.O. que esta zona de memoria puede quedar libre para ser utilizada por otro programa. NOTA: En C siempre es necesario liberar la memoria dinámica. En otros lenguajes (p.ejem JAVA) esto se hace de forma automática a través de un proceso recolector de basura (Garbage Collector) 2. Funciones para la asignación dinámica de memoria (Se encuentran en la librería stdlib.h) Función malloc: void* malloc (numb) – Asigna un espacio de memoria de tamaño numb bytes y devuelve la dirección de comienzo. – Si no hay espacio suficiente devuelve el puntero a NULL – El puntero devuelto es de tipo “no especificado” (void *) por lo que habrá que realizar una conversión de tipos explícita – La función no inicializa el espacio de memoria 3 Ejemplo uso malloc int * p; p=(int *) malloc (4* sizeof(int)); if (p== NULL) printf(“No hay memoria”); else { 1006 //Tratamiento de esa zona //Liberar p 1006 } Memoria dinámica Función calloc void* calloc (nobj,tam) – Asigna un espacio de memoria de tamaño nobj* tam bytes y devuelve la dirección de comienzo. – Si no hay espacio suficiente devuelve el puntero a NULL – El puntero devuelto es de tipo “no especificado” (void *) por lo que habrá que realizar una conversión de tipos explícita – La función inicializa el espacio de memoria a 0. 4 Ejemplo uso calloc int * p; p=(int *) calloc (4,sizeof(int)); if (p== NULL) printf(“No hay memoria”); else { 1006 //Tratamiento de esa zona //Liberar 1006 } 0 0 0 0 p Memoria dinámica Función realloc void* realloc (void *,nb) – Permite redimensionar la zona de memoria que se ha reservado con calloc o malloc. Reseva nb bytes – Se utiliza para reservar más o menos memoria, según se vaya necesitando en cada caso – Si no hay espacio suficiente devuelve el puntero a NULL – El puntero devuelto es de tipo “no especificado” (void *) por lo que habrá que realizar una conversión de tipos explícita – Si el espacio es mayor al anterior la función no inicializa el espacio de memoria extra. – Esta operación es muy costosa, por lo que debe limitarse su uso 5 Ejemplo uso realloc int * p; p=(int *) malloc (4*sizeof(int)); if (p== NULL) printf(“No hay memoria”); 1006 else { //Tratamiento de esa zona p=(int *)realloc(p,6*sizeof(int)); //Liberar 2042 } 1006 2042 3 6 5 4 p Memoria dinámica anterior 3 6 5 4 Nueva memoria dinámica Función free void free ( void *) • Libera el espacio de memoria asignado mediante las funciones calloc, malloc, realloc • De esta forma se indica al S.O. que no se volverá a necesitar esta zona de memoria y que queda libre int * p; p= (int *) malloc (4* sizeof(int)); ....... free (p); 6