Appel de suppression sur la variable allouée sur la stack

En ignorant le style et le design de la programmation, est-il “sûr” d’appeler delete sur une variable allouée sur la stack?

Par exemple:

int nAmount; delete &nAmount; 

ou

 class sample { public: sample(); ~sample() { delete &nAmount;} int nAmount; } 

Non , il n’est pas prudent d’appeler delete sur une variable allouée à la stack. Vous devez uniquement appeler delete sur les éléments créés par new .

  • Pour chaque malloc ou calloc , il devrait y en avoir exactement un free .
  • Pour chaque new il devrait y avoir exactement une delete .
  • Pour chaque new[] il devrait y avoir exactement une delete[] .
  • Pour chaque allocation de stack, il ne doit y avoir aucune libération ou suppression explicite. Le destructeur est appelé automatiquement, le cas échéant.

En général, vous ne pouvez combiner aucun de ces éléments, par exemple, ne pas free ou delete[] un new object. Cela entraîne un comportement indéfini.

Eh bien, essayons:

 jeremy@jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp jeremy@jeremy-desktop:~$ g++ -o test test.cpp jeremy@jeremy-desktop:~$ ./test Segmentation fault 

Donc apparemment ce n’est pas du tout sécuritaire.

Gardez à l’esprit que lorsque vous allouez un bloc de mémoire en utilisant new (ou malloc d’ailleurs), le bloc de mémoire alloué sera plus grand que ce que vous avez demandé. Le bloc de mémoire contiendra également des informations de comptabilité de sorte que lorsque vous libérez le bloc, il peut facilement être replacé dans le pool libre et éventuellement être fusionné avec des blocs libres adjacents.

Lorsque vous essayez de libérer de la mémoire que vous n’avez pas reçue de la nouvelle, cette information comptable ne sera pas là mais le système agira comme il est et les résultats seront imprévisibles (généralement mauvais).

Oui, c’est un comportement indéfini: passer pour delete tout ce qui ne vient pas de new est UB:

Norme C ++, section 3.7.3.2.3: La valeur du premier argument fourni à l’une des fonctions de désallocation fournies dans la bibliothèque standard peut être une valeur de pointeur null ; Dans l’affirmative, et si la fonction de désallocation est une fonction fournie dans la bibliothèque standard, l’appel à la fonction de désallocation est sans effet. Sinon, la valeur fournie à l’ operator delete(void*) dans la bibliothèque standard doit être l’une des valeurs renvoyées par un appel précédent de l’ operator new(std::size_t) ou de l’ operator new(std::size_t, const std::nothrow_t&) dans la bibliothèque standard.

Les conséquences d’un comportement indéfini sont, bien sûr, indéfinies. “Rien ne se passe” est une conséquence aussi valable que toute autre chose. Cependant, c’est généralement “rien ne se passe tout de suite”: la désallocation d’un bloc mémoire invalide peut avoir de graves conséquences lors d’appels ultérieurs à l’allocateur.

Après avoir joué un peu avec g ++ 4.4 dans windows, j’ai obtenu des résultats très intéressants:

  1. L’appel de delete sur une variable de stack ne semble rien faire. Aucune erreur ne se produit, mais je peux accéder à la variable sans problème après la suppression.

  2. Avoir une classe avec une méthode avec delete this supprime l’object avec succès s’il est alloué dans le tas, mais pas s’il est alloué dans la stack (s’il se trouve dans la stack, rien ne se passe).

Personne ne peut savoir ce qui se passe. Cela invoque un comportement indéfini, littéralement tout peut arriver. Ne fais pas ça.

Non, la mémoire allouée à l’aide de new doit être supprimée à l’aide de l’opérateur delete et celle allouée à l’aide de malloc doit être supprimée à l’aide de free. Et pas besoin de désallouer la variable qui est allouée sur la stack.

Un ange perd ses ailes … Vous ne pouvez appeler delete sur un pointeur atsortingbué avec new , sinon vous obtenez un comportement indéfini.

ici la mémoire est allouée à l’aide de la stack, donc pas besoin de la supprimer en externe mais si vous avez allcoted dynamicment

comme int * a = new int ()

alors vous devez supprimer un et ne pas supprimer & a (un lui-même est un pointeur), car la mémoire est allouée à partir du magasin gratuit.

Vous avez déjà répondu à la question vous-même. delete ne doit être utilisé que pour les pointeurs choisis via new . Faire n’importe quoi d’autre est un comportement simple et non défini.

Par conséquent, rien ne dit ce qui se passe: tout ce qui fonctionne bien à partir du code en passant par l’effondrement de votre disque dur est une conséquence valable. Alors s’il vous plaît ne faites jamais cela .

C’est UB car vous ne devez pas appeler delete sur un élément qui n’a pas été alloué dynamicment avec new. C’est si simple.