Utilisation de realloc pour réduire la mémoire allouée

Question Simple sur la fonction realloc en C: Si j'utilise realloc pour réduire le bloc de mémoire vers lequel pointe un pointeur, la mémoire "supplémentaire" est-elle libérée? Ou doit-il être libéré manuellement d'une manière ou d'une autre?

Par exemple, si je fais

int *myPointer = malloc(100*sizeof(int));
myPointer = realloc(myPointer,50*sizeof(int));
free(myPointer);

Vais - je avoir une fuite de mémoire?

22
demandé sur Moshe Rosenschein 2011-08-16 16:11:39

4 réponses

Non, vous n'aurez pas de fuite de mémoire. {[0] } marquera simplement le reste "disponible" pour les futures opérations malloc.

Mais vous devez toujours free myPointer plus tard. En aparté, si vous utilisez 0, comme la taille de realloc, il aura le même effet que free dans certaines implémentations. Comme Steve Jessop et R.. dit dans les commentaires, vous ne devriez pas compter sur elle.

17
répondu cnicutar 2011-08-16 12:38:17

Il n'y a certainement pas de fuite de mémoire, mais au moins 3 choses pourraient arriver lorsque vous appelez realloc pour réduire la taille:

  1. L'implémentation divise le bloc de mémoire alloué à la nouvelle longueur demandée et libère la partie inutilisée à la fin.
  2. L'implémentation effectue une nouvelle allocation avec la nouvelle taille, copie l'ancien contenu vers le nouvel emplacement et libère toute l'ancienne allocation.
  3. L'implémentation ne fait rien du tout.

Option 3 ce serait une implémentation plutôt mauvaise, mais parfaitement légale; il n'y a toujours pas de "fuite de mémoire" car le tout sera toujours libéré si vous appelez plus tard free dessus.

En ce qui concerne les options 1 et 2, ce qui est mieux dépend beaucoup de savoir si vous favorisez les performances ou si vous évitez la fragmentation de la mémoire. Je crois que la plupart des implémentations du monde réel se pencheront vers l'option 1.

14
répondu R.. 2011-08-16 12:31:02

Le nouveau code fuit toujours l'allocation d'origine si le realloc échoue. Je m'attends à ce que la plupart des implémentations ne parviennent jamais à réduire un bloc, mais c'est autorisé. La façon correcte d'appeler realloc, que ce soit en augmentant ou en réduisant le bloc, est void *tmp = realloc(myPointer, 50*sizeof(int)); if (!tmp) { /* gérer l'erreur en quelque sorte. myPointer pointe toujours vers l'ancien bloc, qui est toujours alloué */} myPointer = tmp;. – Steve Jessop il y a 48 minutes

Hey, je ne pouvais pas comprendre comment répondre à votre commentaire, désolé.

Dois-je convertir tmp en type de myPointer? Dans ce cas, dois-je écrire

myPointer = (int*)tmp

Aussi, dans ce cas, quand je fais gratuit (myPointer) La mémoire pointée par tmp sera également libérée, Non? Donc pas besoin de faire

free(myPointer)
free(tmp)
4
répondu azphare 2011-08-16 13:36:50

De la façon dont vous avez donné votre code, oui, il pourrait y avoir une fuite. L'idée de realloc est qu'il peut vous renvoyer un nouvel emplacement de vos données. Comme vous le faites dans votre question, vous perdez ce pointeur realloc vous envoie.

int *myPointer2 = realloc(myPointer,50*sizeof(int));
assert(myPointer2); 
myPointer = myPointer2;
3
répondu Jens Gustedt 2011-08-16 12:37:26