Memoria Dinámica en C. Clase 13

Anuncio
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?
Descargar