web-dev-qa-db-fra.com

La réallocation remplace-t-elle l'ancien contenu?

Lorsque nous réallouons la mémoire via realloc(), le contenu précédent est-il écrasé? J'essaie de créer un programme qui réalloue la mémoire chaque fois que nous y entrons les données.

Veuillez me parler de l'allocation de mémoire via realloc, est-ce que cela dépend du compilateur par exemple?

36
fuddin

Ne vous inquiétez pas de l'ancien contenu.

La bonne façon d'utiliser realloc est d'utiliser un pointeur spécifique pour la réallocation, de tester ce pointeur et, si tout s'est bien passé, de changer l'ancien pointeur

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 */
85
pmg

Il augmente la mémoire déjà allouée sans écraser le contenu existant, ou (s'il ne peut pas se développer), il alloue une nouvelle mémoire plus grande à un emplacement différent et copie le contenu existant de la mémoire précédente dans la nouvelle mémoire.

12
ChrisW

Vous devez programmer comme si l'ancien pointeur était écrasé, oui. L'ancienne mémoire n'est plus allouée et peut donc être réallouée par une autre partie de votre programme (ou un thread système par exemple) et écrasée à tout moment après avoir appelé realloc.

La nouvelle mémoire contiendra toujours les mêmes données qui étaient présentes dans l'ancienne mémoire (elle est copiée pour vous si nécessaire), mais uniquement jusqu'à la taille de l'ancien bloc, tout espace supplémentaire alloué à la fin ne sera pas initialisé.

Si vous voulez une copie, faites un nouveau malloc et utilisez memcpy.

En termes d'implémentation, lorsque vous appelez realloc à augmenter la taille, l'une des choses suivantes peut se produire:

  • Un nouveau bloc est alloué et le contenu de l'ancienne mémoire copié, l'ancien bloc est libéré, le nouveau pointeur est renvoyé.
  • Si la zone après le bloc n'est pas allouée, le bloc existant peut être étendu et le même pointeur renvoyé.

Puisque vous n'avez aucun moyen de savoir ce qui s'est passé, ou même si une implémentation complètement différente de celle suggérée ci-dessus est utilisée, vous devez toujours coder selon la spécification de realloc, c'est-à-dire que vous ne devez plus utiliser l'ancien pointeur et vous doit utiliser le nouveau.

9
jhabbott

Il est difficile de dire ce que vous demandez, mais si vous demandez si vous pouvez lire "l'ancien contenu" à l'ancienne adresse passée à realloc, la réponse est no. Dans certains cas, vous pouvez y trouver tout ou partie de l'ancien contenu, mais à moins que realloc ne renvoie le même pointeur que vous lui avez transmis, toute utilisation de l'ancien pointeur est indéfinie comportement .

Si vous demandez simplement si l'ancien contenu sera conservé à la nouvelle adresse renvoyée par realloc, la réponse est oui (jusqu'au minimum de l'ancienne taille et de la nouvelle taille).