135 votes

Pourquoi la suppression ne met pas le pointeur à NULL ?

Je me suis toujours demandé pourquoi la mise automatique du pointeur à NULL après supprimer ne fait pas partie de la norme. Si cela est pris en charge, de nombreux crashs dus à un pointeur invalide ne se produiront pas. Ceci étant dit, je peux penser à quelques raisons pour lesquelles la norme aurait restreint ce point :

  1. Performance :

    Une instruction supplémentaire pourrait ralentir le delete performance.

  2. Serait-ce à cause de const les pointeurs.

    Mais la norme aurait pu faire quelque chose pour ce cas particulier, je suppose.

Quelqu'un connaît-il les raisons exactes de cette interdiction ?

158voto

Dan Olson Points 11210

Stroustrup lui-même réponses. Un extrait :

Le C++ autorise explicitement une implémentation de delete de mettre à zéro une opérande de valeur l, et j'avais espéré que les implémentations le feraient, mais cette idée ne semble pas être être devenue populaire auprès des implémenteurs.

Mais le principal problème qu'il soulève est que l'argument de delete ne doit pas nécessairement être une lvalue.

1 votes

Je pense que des explications supplémentaires seraient utiles. Je ne suis même pas sûr de ce qu'il dit... Je suppose que je devrai revenir plus tard quand je pourrai consacrer quelques heures à la recherche jusqu'à ce que je comprenne. Ou, vous pourriez développer la réponse pour nous aider à comprendre plus rapidement.

0 votes

Il serait bien que le delete standard soit surchargé pour lvalue & rvalue, de sorte qu'il mette l'argument à nullptr quand c'est une lvalue.

67voto

sharptooth Points 93379

Tout d'abord, la mise à zéro nécessiterait une variable stockée en mémoire. Il est vrai que vous avez généralement un pointeur dans une variable mais parfois vous pouvez vouloir supprimer un objet à une adresse qui vient d'être calculée. Cela serait impossible avec la suppression "annulante".

Viennent ensuite les performances. Vous avez peut-être écrit le code de telle manière que le pointeur sort de son champ d'application immédiatement après que supprimer est fait. Le remplir de null est juste une perte de temps. Et le C++ est un langage avec l'idéologie du "vous n'en avez pas besoin ? alors vous n'avez pas à payer pour ça".

Si vous avez besoin de sécurité, il existe un large éventail de pointeurs intelligents à votre service ou vous pouvez écrire le vôtre - mieux et plus intelligemment.

5 votes

Bon point concernant l'adresse calculée, même si c'est quelque chose que vous ne voyez pas souvent.

0 votes

Parlez-vous du placement de nouveaux objets lorsque vous dites que parfois vous pourriez vouloir supprimer un objet à une adresse juste calculée. ? ??

0 votes

@PravasiMeet Non, je veux dire quelque chose comme delete (ptr + i)

42voto

AaronLS Points 12720

Vous pouvez avoir plusieurs pointeurs pointant vers cette mémoire. Cela créerait un faux sentiment de sécurité si le pointeur que vous avez spécifié pour la suppression était défini comme nul, mais que tous les autres pointeurs ne l'étaient pas. Un pointeur n'est rien d'autre qu'une adresse, un nombre. Il pourrait tout aussi bien être un int avec une opération de déréférencement. Ce que je veux dire, c'est qu'il faudrait également analyser chaque pointeur pour trouver ceux qui font référence à la même mémoire que celle que vous venez de supprimer, et les annuler également. Il serait très coûteux de scanner tous les pointeurs pour cette adresse et de les annuler, car le langage n'est pas conçu pour cela. (Bien que certains autres langages structurent leurs références pour accomplir un objectif similaire d'une manière différente).

20voto

sth Points 91594

Un pointeur peut être sauvegardé dans plus d'une variable, mettre l'une d'entre elles à NULL laisserait toujours des pointeurs invalides dans les autres variables. Vous ne gagnez donc pas grand-chose, vous créez plutôt un faux sentiment de sécurité.

En plus de cela, vous pouvez créer votre propre fonction qui fait ce que vous voulez :

template<typename T>
void deleten(T *&ptr) {
  delete ptr;
  ptr = NULL;
}

12voto

snemarch Points 3328

Parce qu'il n'y a pas vraiment besoin de le faire, et parce que cela nécessiterait que la suppression prenne le pointeur-à-pointeur plutôt que le simple pointeur.

0 votes

C'est vrai, mais cela entraînerait la même surcharge.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X