¿Realloc sobrescribe contenidos antiguos?


Cuando reasignamos la memoria a través de realloc(), ¿se sobreescriben los contenidos anteriores? Estoy tratando de hacer un programa que reasigne la memoria cada vez que ingresamos los datos en él.

Por favor, hábleme de la asignación de memoria a través de realloc, ¿depende del compilador, por ejemplo?

 30
Author: PaulG, 2010-10-03

4 answers

No te preocupes por el contenido antiguo.

La forma correcta de usar realloc es usar un puntero específico para la reasignación, probar ese puntero y, si todo salió bien, cambiar el puntero anterior

int *oldpointer = malloc(100);

/* ... */

int *newpointer = realloc(oldpointer, 1000);
if (newpointer == NULL) {
    /* problems!!!!                                 */
    /* tell the user to stop playing DOOM and retry */
    /* or free(oldpointer) and abort, or whatever   */
} else {
    /* everything ok                                                                 */
    /* `newpointer` now points to a new memory block with the contents of oldpointer */
    /* `oldpointer` points to an invalid address                                     */
    oldpointer = newpointer;
    /* oldpointer points to the correct address                                */
    /* the contents at oldpointer have been copied while realloc did its thing */
    /* if the new size is smaller than the old size, some data was lost        */
}

/* ... */

/* don't forget to `free(oldpointer);` at some time */
 71
Author: pmg,
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
2010-10-03 17:32:03

Crece la memoria ya asignada sin sobrescribir el contenido existente, o (si no puede crecer) asigna nueva memoria más grande en una ubicación diferente y copia el contenido existente de la memoria anterior en una nueva memoria.

 11
Author: ChrisW,
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
2010-10-03 17:20:37

Debe programar como si el puntero antiguo se sobrescribiera, sí. La memoria antigua ya no está asignada, por lo que puede ser reasignada por otra parte de su programa (o un subproceso del sistema, por ejemplo) y escrita en cualquier momento después de llamar a realloc.

La nueva memoria siempre contendrá los mismos datos que estaban presentes en la memoria antigua (se copia para usted si es necesario), pero solo hasta el tamaño del bloque antiguo, cualquier espacio adicional asignado al final será sin inicializar.

Si quieres una copia entonces haz un nuevo malloc y usa memcpy.

En cuanto a la implementación, cuando llamas a realloc a increase el tamaño, una de estas cosas podría suceder:

  • Se asigna un nuevo bloque y se copia el contenido de la memoria antigua, se libera el bloque antiguo y se devuelve el nuevo puntero.
  • Si el área después del bloque no es asignada, el bloque existente puede ser extendido y el mismo puntero devuelto.

Ya que tienes no hay forma de saber lo que ha sucedido, o incluso si se utiliza una implementación completamente diferente a la sugerida anteriormente, siempre debe codificar de acuerdo con la especificación de realloc, que es que no debe usar el puntero antiguo más y debe usar el nuevo.

 9
Author: jhabbott,
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
2010-10-03 17:25:35

Es difícil decir lo que estás preguntando, pero si estás preguntando si puedes leer el "contenido antiguo" en la dirección antigua pasada a realloc, la respuesta es no. En algunos casos, puede encontrar parte o todo el contenido antiguo allí, pero a menos que realloc devuelva el mismo puntero que le pasó, cualquier uso del puntero antiguo es un comportamiento indefinido.

Si simplemente está preguntando si el contenido antiguo se conservará en la nueva dirección devuelta por realloc, la respuesta es sí (hasta el mínimo del tamaño antiguo y el nuevo tamaño).

 5
Author: R..,
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
2010-10-03 17:22:58