Memoria Dinámica Herman Schinca Clase 13 10 de Mayo de 2011 Reflexiones Preliminares Hasta ahora trabajamos con variables cuyo tamaño en memoria conocemos: Char → 1 byte Int → 4 bytes Float → 4 bytes Double → 8 bytes Int arr[20] → ? bytes Reflexiones Preliminares ¿En todo programa conocemos TODA la información que vamos a necesitar de antemano? ¿Hay ejemplos en donde esto no ocurra? Reflexiones Preliminares Sí. Ejemplo: Encontrar el máximo número dentro de un conjunto de números ingresado por el usuario. A priori no sabemos cuántos números deseará ingresar por lo que ello se decidirá dinámicamente en tiempo de ejecución. Reflexiones Preliminares ¿Se les ocurre alguna forma de resolverlo con lo que ya conocen? Solución: Memoria Dinámica Debo, en tiempo de ejecución, indicarle al Sistema Operativo que voy a precisar más memoria y cuánta. malloc: Memory Allocation Allocation = Asignación Allocation ≠ Alocar Alocar = Causar locura Luego, la memoria no se aloca. malloc: Aridad void* malloc(cantBytes) Se le piden cantBytes al SO. Devuelve un puntero a donde comienza dicha memoria o NULL sino. Nota: Debo castear void al tipo de datos al que va a apuntar el puntero. malloc: Ejemplo int cant; scanf("%d",&cant); int* arr; arr = (int*) malloc(cant*sizeof(int)); int i; for(i=0; i<cant; i++){ scanf("%d",&arr[i]); } malloc: Ejemplo ¿Y eso es todo? No, debo chequear que obtuve dicha memoria o informar de lo contrario (no es obligatorio mas sí muy conveniente). malloc: Ejemplo ... int* arr; arr = (int*) malloc(cant*sizeof(int)); loquito!”); if(arr==NULL){ printf(“Zarpaste en memoria, } ... exit(EXIT_FAILURE); malloc: Ejemplo Bueno, ahora sí, eso es todo... ¿No? Claramente no. Cuando no uso más esa memoria obtenida dinámicamente, debo “devolverla” pues la “pedí prestada”. free: Libérala Hermano! free(arr) Libera la memoria asignada al puntero arr. Matrices ¡Arreglo de arreglos! Cada uno puede tener distinto tamaño. Luego, más general que una matriz aún. Debo pedir memoria para el arreglo de arreglos y para cada uno de esos arreglos. Matrices: Pido Memoria int filas, cols; scanf("%d %d",&filas, &cols); int** arr; arr = (int**) malloc(filas*sizeof(int*)); //Chequeo si arr==NULL int i; for(i=0; i<filas; i++){ arr[i] = (int*) malloc(cols*sizeof(int)); //Chequeo si arr[i]==NULL } Matrices: Libero Memoria for(i=0; i<filas; i++){ free(arr[i]); } free(arr); miniEjercicio Hallar la traspuesta de una matriz ingresada por el usuario desde el teclado y guardarla en un archivo de texto. ¿Cómo la guardarían? Nota: traspuesta(A)ij = Aji donde A es de nxm y A traspuesta es de mxn calloc: Clear Allocation void* calloc(cantElems, bytesElem) Reserva memoria para cantElems de tamaño bytesElem, es decir, cantElems*bytesElem bytes de memoria. Sino, devuelve NULL. malloc vs calloc malloc no inicializa la memoria. calloc pone un 0 en cada elemento del array. Luego, calloc es más costosa temporalmente ya que debe recorrer todo el arreglo y ponerle 0's. realloc: Re-allocation void* realloc(void* ptr, cantBytes) Reasigna cantBytes de memoria y copia lo apuntado por ptr a la nueva dirección de memoria. realloc: Ejemplo //arr = [4, 25, 35] arr= (int*) realloc(arr, 4*sizeof(int)); arr[3] = 72 //arr = [4, 25, 35, 72] Resumen malloc para pedir memoria. calloc para pedir memoria inicializada en 0. realloc para reasignar memoria (potencialmente pidiendo más). free para liberar memoria después de su uso. C'est fini ¿Questions?