supprimer vs NULL vs gratuit en C++

Quelle est la différence entre supprimer un pointeur, le mettre à null et le libérer.

delete ptr;

Vs.

ptr=NULL;

Vs.

free(ptr);
34
c
demandé sur Steve Rowe 2010-05-26 10:34:33

6 réponses

Votre question suggère que vous venez d'une langue qui a la collecte des ordures. C++ n'a pas de récupération de place.

Si vous définissez un pointeur sur NULL, cela ne provoque pas le retour de la mémoire dans le pool de mémoire disponible. Si aucun autre pointeur ne pointe vers ce bloc de mémoire, vous avez Maintenant simplement un bloc de mémoire" orphelin " qui reste alloué mais est maintenant inaccessible - une fuite . Les fuites ne provoquent un plantage d'un programme que si elles s'accumulent jusqu'à un point où aucune mémoire n'est de gauche à allouer.

Il y a aussi la situation inverse, où vous delete un bloc de mémoire en utilisant un pointeur, et essayez plus tard d'accéder à cette mémoire comme si elle était toujours allouée. Ceci est possible car l'appel de delete sur un pointeur ne définit pas le pointeur sur NULL - il pointe toujours vers l'adresse de la mémoire précédemment allouée. Un pointeur vers la mémoire qui n'est plus alloué est appelé un pointeur dangling et y accéder provoquera généralement comportement du programme étrange et plantages, puisque son contenu n'est probablement pas ce que vous attendez - ce morceau de mémoire peut avoir depuis été réaffecté à d'autres fins.

[EDIT] {[12] } comme le mentionne stinky472, une autre différence entre delete et free() est que seul le premier appelle le destructeur de l'objet. (N'oubliez pas que vous devez appeler delete sur un objet alloué avec new, et free() pour mémoire allouée avec malloc() -- ils ne peuvent pas être mélangés. En C++, il est toujours préférable d'utiliser allocation statique si possible, mais sinon, préférez new à malloc().

46
répondu j_random_hacker 2010-06-27 12:42:34

delete donnera la mémoire allouée à la bibliothèque d'exécution c++. Vous avez toujours besoin d'un new correspondant, qui a alloué la mémoire sur le tas avant. NULL est quelque chose de complètement différent. Un "espace réservé" pour signifier qu'il ne pointe vers aucune adresse. En C++, NULL est une MACRO définie comme 0. Donc, si vous n'aimez pas les MACROS, l'utilisation directe de 0 est également possible. En C++0x nullptr est introduit et préférable.

Exemple:

int* a;        //declare pointer
a = NULL;      //point 'a' to NULL to show that pointer is not yet initialized 
a = new int;   //reserve memory on the heap for int

//... do more stuff with 'a' and the memory it points to

delete a;      //release memory
a = NULL;      //(depending on your program), you now want to set the pointer back to
               // 'NULL' to show, that a is not pointing to anything anymore
26
répondu Lucas 2010-05-26 07:01:59

Eh bien, si vous avez créé un objet dynamiquement (avec 'new'), définir le pointeur sur n'importe quelle valeur ne supprime pas l'objet de la mémoire - et vous obtenez une fuite de mémoire.

5
répondu foret 2010-05-26 06:37:21

, Comme avec n'importe quel indirection, il y a deux objets impliqués lors de l'utilisation de pointeurs: l'référent (le pointeur, dans votre exemple ptr) et la objet référencé (ce qu'il désigne, *ptr). Vous devez apprendre à différencier entre eux.

Lorsque vous affectez NULL pour un pointeur, seul le pointeur est affectée, l'objet qu'il désigne est laissé seul. Si le pointeur était le dernier pointant vers cet objet, vous ont perdu le dernier pointeur de référence pointant vers lui et ne peuvent donc plus l'utiliser. En C++, cependant, cela ne signifie pas que l'objet sera supprimé. C++ ne possède pas de collecte des ordures. Si l'objet est fuite.

Pour supprimer les objets, vous devrez les supprimer manuellement en passant leur adresse (stockées dans un pointeur) de la delete opérateur. Si vous faites cela,, seul l'objet visé pour sera affecté, le pointeur est laissé seul. Il peut toujours pointer vers l'adresse où l'objet résidait en mémoire, même si cela n'est plus utilisable. C'est ce qu'on appelle un pointeur balançant.

4
répondu sbi 2010-05-26 07:05:29

Lorsque vous créez un objet à l'aide de new, Vous devez utiliser delete pour libérer sa mémoire dans le système. La mémoire sera alors disponible pour d'autres à réutiliser.


int* a = new int;
delete a;

NULL est juste une macro prédéfinie à laquelle on peut attribuer un pointeur pour signifier qu'elle ne pointe vers rien.


int* a = new int;
a = NULL;

Dans le cas ci-dessus, après l'allocation de stockage pour a, vous lui attribuez NULL. Cependant, la mémoire précédemment allouée pour a n'a pas été libérée et ne peut pas être réutilisée par le système. C'est ce que nous appelons fuite de mémoire.

2
répondu jasonline 2010-05-26 06:46:39
int * ptr = null;

Appeler free(ptr) ne fera rien. Selon la norme si le pointeur donné est null, aucune action ne se produit.

Utiliser delete p ne fera rien non plus. La norme C++ indique qu'aucune action ne se produira car elle ne pointe vers rien et qu'aucun type n'est disponible.

1
répondu Vijay Singh 2012-08-08 12:42:04