Usando realloc para reducir la memoria asignada
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?
4 answers
No, no tendrás una fuga de memoria. realloc
simplemente marcará el resto como "disponible" para futuras operaciones malloc
.
Pero todavía tienes que free
myPointer
más tarde. Como un aparte, si se uso 0
como el tamaño en realloc
, tendrá el mismo efecto que free
en algunas implementaciones. Como Steve Jessop y R.. dicho en los comentarios, no debes confiar en él.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-16 12:38:17
Definitivamente no hay una fuga de memoria, pero cualquiera de al menos 3 cosas podrían suceder cuando llamas 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 el contenido antiguo a la nueva ubicación y libera toda la asignación antigua.
- La implementación no hace nada en absoluto.
Opción 3 sería una implementación bastante mala, pero perfectamente legal; todavía no hay "fuga de memoria" porque todo seguirá siendo liberado si luego llamas free
en él.
En cuanto a las opciones 1 y 2, que es mejor depende mucho de si se favorece el rendimiento o evitar 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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-16 12:31:02
El nuevo código aún filtra la asignación original si el realloc falla. Espero que la mayoría de las implementaciones nunca fallen en reducir un bloque, pero está permitido. La forma correcta de llamar a realloc, ya sea creciendo o reduciendo el bloque, es void * tmp = realloc (myPointer,50 * sizeof (int)); if (!tmp) {/*manejar el error de alguna manera. myPointer todavía apunta al bloque antiguo, que todavía está asignado*/} myPointer = tmp;. - Steve Jessop hace 48 minutos
Hey, no podía averiguar cómo responder a su comentario, lo siento.
¿Necesito convertir tmp al tipo de myPointer? En este caso, necesito escribir
myPointer = (int*)tmp
También, en este caso, cuando lo hago gratis (myPointer) La memoria señalada por tmp será liberada también, ¿verdad? Así que no hay necesidad de hacer
free(myPointer)
free(tmp)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-16 13:36:50
En 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. Como lo haces en tu pregunta pierdes ese puntero que realloc
te envía.
int *myPointer2 = realloc(myPointer,50*sizeof(int));
assert(myPointer2);
myPointer = myPointer2;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-16 12:37:26