Libération de la mémoire allouée: realloc () vs free ()

donc j’ai un morceau de mémoire alloué avec malloc() et changé plus tard avec realloc() .

À un moment donné de mon code, je veux le vider. Par là, je veux dire essentiellement lui donner la mémoire de 0. Quelque chose qui serait intuitivement fait avec realloc(pointer,0) . J’ai lu ici qu’il s’agit d’une définition d’implémentation et qu’elle ne devrait pas être utilisée.

Devrais-je plutôt utiliser free() , puis faire un autre malloc() ?

Cela dépend de ce que vous voulez dire: si vous voulez vider la mémoire utilisée , mais que vous avez toujours access à cette mémoire, utilisez memset(pointer, 0, mem_size); , pour réinitialiser ladite mémoire à zéro.
Si vous n’avez plus besoin de cette mémoire, vous appelez simplement free(pointer); , ce qui libère la mémoire, donc elle peut être utilisée ailleurs.

L’utilisation de realloc(pointer, 0) peut fonctionner comme sur votre système, mais ce n’est pas le comportement standard. realloc(ptr, 0) n’est pas spécifié par les normes C99 ou C11 comme étant l’équivalent de free(ptr) .

realloc(pointer, 0) n’est pas équivalent à free(pointer) .

La norme (C99, § 7.22.3.5):

 La fonction realloc
 Synopsis
 1
 #include 
 void * realloc (void * ptr, size_t size);

 La description
 2 La fonction realloc libère l'ancien object pointé par ptr et renvoie un
 pointeur sur un nouvel object dont la taille est spécifiée par taille.  Le contenu de la nouvelle
 object doit être le même que celui de l'ancien object avant la désallocation, jusqu'au moindre des deux montants suivants:
 les nouvelles et anciennes tailles.  Tous les octets du nouvel object dépassant la taille de l'ancien ont
 valeurs indéterminées.
 3 Si ptr est un pointeur nul, la fonction realloc se comporte comme la fonction malloc pour le
 taille spécifiée.  Sinon, si ptr ne correspond pas à un pointeur précédemment renvoyé par une mémoire
 fonction de gestion, ou si l’espace a été libéré par un appel à la fonction libre ou
 fonction realloc, le comportement est indéfini.  Si la mémoire pour le nouvel object ne peut pas être
 alloué, l'ancien object n'est pas désalloué et sa valeur rest inchangée.
 Résultats
 4
 La fonction realloc renvoie un pointeur sur le nouvel object (qui peut avoir le même object
 valeur en tant que pointeur sur l'ancien object), ou un pointeur NULL si le nouvel object ne peut pas être
 alloué.

Comme vous pouvez le constater, il ne spécifie pas de cas particulier pour les appels realloc dont la taille est égale à 0. Il indique uniquement qu’un pointeur NULL est renvoyé en cas d’allocation de mémoire, et un pointeur dans tous les autres cas. Un pointeur pointant sur 0 octet serait alors une option viable.

Pour citer une question connexe :

Plus intuitivement, realloc est “conceptuellement équivalent” à malloc + memcpy + free sur l’autre pointeur, et Malloc-ing une partie de mémoire de 0 octet renvoie NULL, soit un pointeur unique, à ne pas utiliser pour stocker quoi que ce soit (vous avez demandé pour 0 octets), mais rest à libérer. Donc, non, n’utilisez pas realloc comme cela, cela pourrait fonctionner avec certaines implémentations (notamment Linux), mais ce n’est certainement pas garanti.

Comme autre réponse à cette question liée, le comportement de realloc(ptr, 0) est explicitement défini comme une implémentation définie selon la norme C11 actuelle:

Si la taille de l’espace demandé est égale à zéro, le comportement est défini par l’implémentation: soit un pointeur null est renvoyé, soit le comportement est comme si la taille était une valeur différente de zéro, sauf que le pointeur renvoyé ne doit pas être utilisé pour accéder à un object.

realloc() est utilisé pour augmenter ou diminuer la mémoire et non pour la libérer.

Cochez cette case et utilisez free() pour libérer la mémoire ( link ).

Je ne pense pas que vous voulez dire “vide”; cela signifierait “le définir sur une valeur particulière que je considère comme vide” (souvent tous les bits sont nuls). Vous voulez dire gratuit ou dé-allouer.

La page de manuel dit:

Si ptr est NULL , l’appel est équivalent à malloc(size) , pour toutes les valeurs de size ; si size est égal à zéro et que ptr n’est pas NULL , l’appel est équivalent à free(ptr) .

Traditionnellement, vous pouvez utiliser realloc(ptr, 0); comme synonyme de free(ptr); , tout comme vous pouvez utiliser realloc(NULL, size); comme synonyme de malloc(size); . Je ne le recommanderais pas cependant, c’est un peu déroutant et ce n’est pas la façon dont les gens s’attendent à ce qu’il soit utilisé.

Toutefois , dans le C moderne, la définition a changé: now realloc(ptr, 0); va libérer l’ancienne mémoire, mais ce qui sera fait ensuite n’est pas bien défini: c’est défini par l’implémentation.

Donc: ne faites pas ceci: utilisez free() pour désallouer de la mémoire et laissez realloc() être utilisé uniquement pour changer la taille en un élément non nul.

Utilisez free() pour libérer, pour libérer de la mémoire allouée dynamicment.

Bien que les anciennes documentations indiquent que realloc(p, 0) est équivalent à free(p) , la dernière documentation POSIX indique explicitement que ce n’est pas le cas:

Les versions précédentes autorisaient explicitement un appel à realloc (p, 0) pour libérer l’espace pointé par p et renvoyer un pointeur nul. Bien que ce comportement puisse être interprété comme le permet cette version de la norme, le comité du langage C a indiqué que cette interprétation est incorrecte.

Et de plus:

Les applications doivent supposer que si realloc () renvoie un pointeur null, l’espace pointé par p n’a pas été libéré.

Utilisez free(pointer); pointer = 0 free(pointer); pointer = 0 au lieu de realloc(pointer, 0) .

 void* realloc (void* ptr, size_t size); 

En C90:

Si size est égal à zéro, la mémoire allouée précédemment sur ptr est désallouée comme si un appel à free avait été effectué et un pointeur null est renvoyé.

En C99:

Si la taille est égale à zéro, la valeur de retour dépend de l’implémentation de la bibliothèque particulière: il peut s’agir d’un pointeur null ou d’un autre emplacement qui ne doit pas être déréférencé.

J’utiliserais realloc pour donner à un pointeur plus ou moins de mémoire, mais pas pour le vider. Pour vider le pointeur, j’utiliserais gratuitement.