reservar - Usando realloc para reducir la memoria asignada
que es la memoria dinamica en c (4)
Pregunta simple sobre la función realloc en C: si uso realloc para reducir el bloque de memoria al que apunta un puntero, ¿se libera la memoria "extra"? ¿O necesita ser liberado manualmente de alguna manera?
Por ejemplo, si lo hago
int *myPointer = malloc(100*sizeof(int));
myPointer = realloc(myPointer,50*sizeof(int));
free(myPointer);
¿Tendré una pérdida de memoria?
De la forma en que ha dado su código, sí, podría tener una fuga. La idea de realloc
es que puede devolverle una nueva ubicación de sus datos. Al igual que lo haces en tu pregunta, pierdes el puntero que realloc
te envía.
int *myPointer2 = realloc(myPointer,50*sizeof(int));
assert(myPointer2);
myPointer = myPointer2;
Definitivamente no hay una pérdida de memoria, pero cualquiera de al menos 3 cosas pueden suceder cuando llama a realloc
para reducir el tamaño:
- La implementación divide el bloque de memoria asignado en la nueva longitud solicitada y libera la parte no utilizada al final.
- La implementación hace una nueva asignación con el nuevo tamaño, copia los contenidos antiguos a la nueva ubicación y libera toda la asignación anterior.
- La implementación no hace nada en absoluto.
La opción 3 sería una implementación bastante mala, pero perfectamente legal; todavía no hay "pérdida de memoria" porque todo se liberará si luego llamas free
.
En cuanto a las opciones 1 y 2, lo que es mejor depende mucho de si favorece el rendimiento o evita la fragmentación de la memoria. Creo que la mayoría de las implementaciones del mundo real se inclinarán hacia la opción 1.
El nuevo código aún pierde la asignación original si falla la reasignación. Espero que la mayoría de las implementaciones nunca dejen de reducir un bloque, pero está permitido. La forma correcta de llamar a realloc, ya sea aumentando o reduciendo el bloque, es void * tmp = realloc (myPointer, 50 * sizeof (int)); if (! tmp) {/ * maneja el error de alguna manera. myPointer sigue apuntando al bloque anterior, que todavía está asignado * /} myPointer = tmp ;. - Steve Jessop Hace 48 minutos
Oye, no pude averiguar cómo responder a tu comentario, lo siento.
¿Necesito convertir tmp al tipo de myPointer? En este caso, necesito escribir
myPointer = (int*)tmp
Además, en este caso, cuando lo haga gratis (myPointer), la memoria a la que apunta tmp también se liberará, ¿verdad? Así que no hay necesidad de hacer
free(myPointer)
free(tmp)
No, no tendrás una pérdida de memoria. realloc
simplemente marcará el resto como "disponible" para futuras operaciones de malloc
.
Pero aún tienes que free
myPointer
más tarde. Además, si usa 0
como el tamaño en realloc
, tendrá el mismo efecto que en algunas implementaciones . Como Steve Jessop y R .. dijeron en los comentarios, no debes confiar en ello.