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?
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.
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:
- L'implémentation divise le bloc de mémoire alloué à la nouvelle longueur demandée et libère la partie inutilisée à la fin.
- 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.
- 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.
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)
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;