Free () supprime-t-il les données stockées dans la mémoire allouée dynamicment?

J’ai écrit un programme simple pour tester le contenu d’une mémoire allouée dynamicment après free () comme ci-dessous. (Je sais que nous ne devrions pas accéder à la mémoire après libre. J’ai écrit ceci pour vérifier ce qu’il y aura dans la mémoire après libre)

#include  #include  main() { int *p = (int *)malloc(sizeof(int)); *p = 3; printf("%d\n", *p); free(p); printf("%d\n", *p); } 

sortie: 3 0

Je pensais que cela imprimerait soit des valeurs indésirables, soit un crash de la deuxième déclaration d’impression. Mais il est toujours en train d’imprimer 0.

1) Ce comportement dépend-il du compilateur?

2) si j’essaye de libérer la mémoire deux fois en utilisant free (), le core dump est généré. Dans les pages de manuel, il est mentionné que le comportement du programme est anormal. Mais je reçois toujours le kernel de la décharge. Ce comportement dépend-il également du compilateur?

free() supprime-t-il les données stockées dans la mémoire allouée dynamicment?

N ° free juste libère l’espace alloué indiqué par son argument (pointeur). Cette fonction accepte un pointeur de caractère sur un bloc de mémoire alloué précédemment et le libère, c’est-à-dire l’ajoute à la liste des blocs de mémoire libres, qui peuvent être réaffectés.
La mémoire libérée n’est effacée / effacée d’aucune manière.

Vous ne devez pas déréférencer le pointeur libéré. Standard dit que:

7.22.3.3 La fonction libre:

[…] Sinon, si l’argument ne correspond pas à un pointeur précédemment renvoyé par une fonction de gestion de la mémoire, ou si l’espace a été libéré par un appel à free ou realloc , le comportement est indéfini .

La citation ci-dessus indique également que le fait de libérer un pointeur deux fois appelle un comportement indéfini . Une fois que l’UB est en action, vous pouvez obtenir l’un ou l’autre des résultats inattendus. Il peut y avoir un crash du programme ou un vidage de la mémoire.

Comme décrit sur le site web gnu

La libération d’un bloc modifie le contenu du bloc. Ne vous attendez pas à trouver des données (telles qu’un pointeur sur le prochain bloc d’une chaîne de blocs) dans le bloc après l’avoir libéré.

Ainsi, accéder à un emplacement de mémoire après l’avoir libéré entraîne un comportement indéfini, bien que free ne modifie pas les données de l’emplacement de mémoire. U peut avoir 0 dans cet exemple, u peut aussi bien avoir des ordures dans un autre exemple.

Et, si vous essayez de désallouer la mémoire deux fois, lors de la deuxième tentative, vous essayez de libérer une mémoire qui n’est pas allouée, c’est pourquoi vous récupérez le dump principal.

En ce qui concerne la norme C, elle n’est tout simplement pas spécifiée, car elle n’est pas observable. Dès que vous free mémoire, tous les pointeurs pointant vers là sont invalides, il n’y a donc aucun moyen d’inspecter cette mémoire. *)

Même si vous avez une bibliothèque C standard qui documente un comportement donné, votre compilateur peut toujours supposer que les pointeurs ne sont pas réutilisés après avoir été passés à free , vous ne pouvez donc pas vous attendre à un comportement particulier.

*) Je pense que, même en lisant ces indications, c’est UB, pas seulement la déréférence, mais cela n’a pas d’importance ici.

En plus de toutes les explications ci-dessus pour la sémantique use-after-free, vous voudrez peut-être étudier la possibilité de sauver des vies pour chaque programmeur C: valgrind. Il détectera automatiquement de tels bogues dans votre code et sauvegardera généralement vos erreurs dans le monde réel. Coverity et tous les autres vérificateurs de code statiques sont également excellents, mais valgrind est génial.