Théoriquement, je peux dire que
free(ptr);
free(ptr);
est une corruption de mémoire puisque nous libérons la mémoire qui a déjà été libérée.
Mais si
free(ptr);
ptr=NULL;
free(ptr);
Comme le système d'exploitation se comportera d'une manière indéfinie, je ne peux pas obtenir une analyse théorique réelle de ce qui se passe. Quoi que je fasse, cette mémoire est-elle corrompue ou non?
La libération d'un pointeur NULL est-elle valide?
delete NULL
n'est pas valide en C ++. delete peut être appliqué à des valeurs de pointeur nul de type concret, mais pas àNULL
.delete (int*) NULL
est légal, mais pasdelete NULL
.ptr
pointe vers la mémoire et que vous ne l'appelez pasfree
, la mémoire fuira. Le paramétrer surNULL
perd simplement votre maîtrise de la mémoire et des fuites. Siptr
cela se produitNULL
, l'appelfree
est une non-opération.free(ptr)
parptr = NULL
. Personne n'a rien dit de tel.Réponses:
Voir ISO-CEI 9899 .
Cela étant dit, en regardant différentes bases de code dans la nature, vous remarquerez que les gens font parfois:
C'est parce que certains runtimes C (je me souviens bien que c'était le cas sur PalmOS) plantaient lors de la libération d'un
NULL
pointeur.Mais de nos jours, je pense qu'il est prudent de supposer que
free(NULL)
c'est un non conformément aux instructions de la norme.la source
free(ptr)
oùptr
est nul n'a aucun effet secondaire. Mais dans tous les cas, chaque mémoire allouée en utilisantmalloc()
oucalloc()
doit être libérée par la suite en utilisantfree()
free(NULL)
en testant le pointeurNULL
avant d'appelerfree()
Toutes les versions conformes aux normes de la bibliothèque C traitent free (NULL) comme un no-op.
Cela dit, à un moment donné, il y avait des versions de free qui plantaient sur free (NULL), c'est pourquoi vous pouvez voir certaines techniques de programmation défensives recommandées:
la source
dit la documentation.
la source
Je me souviens avoir travaillé sur PalmOS où
free(NULL)
s'est écrasé.la source
NULL
était l'une des grandes différences de fonctionnement de la boîte à outils Palm par rapport à la bibliothèque standard.Vous pouvez supprimer en toute sécurité un pointeur NULL. Aucune opération ne sera effectuée dans ce cas, en d'autres termes free () ne fait rien sur un pointeur NULL.
la source
Utilisation recommandée:
Voir:
Lorsque vous réglez le pointeur sur
NULL
après,free()
vous pouvez le rappelerfree()
et aucune opération ne sera effectuée.la source
free(NULL)
est parfaitement légal en C, ainsi quedelete (void *)0
etdelete[] (void *)0
sont légaux en C ++.BTW, libérer de la mémoire deux fois provoque généralement une sorte d'erreur d'exécution, donc cela ne corrompe rien.
la source
delete 0
n'est pas légal en C ++.delete
nécessite explicitement une expression de type pointeur. Il est légal de s'appliquerdelete
à une valeur de pointeur nul typée, mais pas à0
(et pas àNULL
).void*
: P Quels destructeurs doit-il exécuter?void *
tant qu'il s'agit d'un pointeur nul.buf1=malloc(X); free(buf1);buf2=malloc(X);free(buf1);
- ici, si vous êtes malchanceux, buf2 a exactement la même adresse que buf1, et vous avez accidentellement libéré buf1 deux fois, donc le 2ème libre de buf1 vous avez en fait libéré buf2 silencieusement, sans casse toute erreur (immédiate) / crash / peu importe. (mais vous aurez probablement toujours un crash la prochaine fois que vous essayez d'utiliser buf2 - et ce scénario est très peu probable si vous utilisez ASLR)free(ptr)
est sauf en C siptr
estNULL
, cependant, que la plupart des gens ne savent pas est queNULL
n'a pas besoin d' être égal à 0. J'ai un bel exemple de la vieille école: Sur la C64, sur l' adresse 0, il y a un IO-Port. Si vous avez écrit un programme en C accédant à ce port, vous auriez besoin d'un pointeur dont la valeur est 0. La bibliothèque C correspondante devrait faire la distinction entre 0 etNULL
alors.Sincères amitiés.
la source
pas de corruption de mémoire, mais le comportement dépend de la mise en œuvre. En règle générale, ce devrait être un code juridique.
la source
ptr pointe vers un emplacement mémoire, disons 0x100.
Lorsque vous libérez (ptr), vous autorisez essentiellement l'utilisation de 0x100 par le gestionnaire de mémoire pour d'autres activités ou processus et, en termes simples, il s'agit de la désallocation des ressources.
Lorsque vous faites ptr = NULL, vous faites pointer ptr vers un nouvel emplacement (ne vous inquiétez pas de ce qu'est NULL). En faisant cela, vous avez perdu la trace des données de la mémoire 0x100. C'est ce qui est une fuite de mémoire.
Il n'est donc pas conseillé d'utiliser ptr = NULL sur un ptr valide.
Au lieu de cela, vous pouvez effectuer une vérification en toute sécurité en utilisant:
if (ptr! = NULL) {libre (ptr);}
Lorsque vous libérez (ptr) où ptr pointe déjà vers NULL, il n'effectue aucune opération.
la source