Pourquoi la suppression ne définit-elle pas le pointeur sur NULL?

Je me suis toujours demandé pourquoi le réglage automatique du pointeur sur NULL après suppression ne faisait pas partie de la norme. Si cela est pris en charge, la plupart des accidents dus à un pointeur invalide ne se produiront pas. Mais après avoir dit cela, je peux penser à deux raisons pour lesquelles la norme aurait limité cela:

  1. Performance:

    Une instruction supplémentaire pourrait ralentir les performances de delete .

  2. Pourrait-il être à cause des pointeurs const .

    Là encore, la norme aurait pu faire quelque chose pour ce cas particulier, je suppose.

Est-ce que quelqu’un connaît les raisons exactes de ne pas permettre cela?

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

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

    Mais le principal problème qu’il soulève est que l’argument de suppression ne doit pas être une lvalue.

    Tout d’abord, la définition sur null nécessite une variable stockée en mémoire. Il est vrai que vous avez généralement un pointeur dans une variable, mais que vous souhaitiez parfois supprimer un object à une adresse juste calculée. Cela serait impossible avec la suppression de “nullification”.

    Puis vient la performance. Vous avez peut-être écrit du code de manière à ce que le pointeur disparaisse immédiatement après la suppression . Le remplir avec null est juste une perte de temps. Et C ++ est un langage avec “ne pas en avoir besoin? Alors vous n’avez pas à payer pour cela”.

    Si vous avez besoin de sécurité, il existe un large éventail de pointeurs intelligents à votre service ou vous pouvez rédiger votre propre sharepoint vue – meilleur et plus intelligent.

    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 sur null, mais pas sur tous les autres pointeurs. Un pointeur n’est rien d’autre qu’une adresse, un numéro. Cela pourrait aussi bien être un int avec une opération de déréférencement. Ce que je veux dire, c’est que vous devez également parsingr chaque pointeur pour trouver ceux qui référencent la même mémoire que vous venez de supprimer et les annuler également. Analyser tous les pointeurs de cette adresse et les annuler parce que le langage n’a pas été conçu pour cela, ce serait très compliqué sur le plan informatique. (Bien que d’autres langues structurent leurs références pour atteindre un objective similaire d’une manière différente.)

    Un pointeur peut être enregistré dans plusieurs variables, la définition de l’une d’entre elles sur NULL laisserait toujours des pointeurs non valides dans les autres variables. Donc, vous ne gagnez pas vraiment beaucoup, vous êtes plus susceptible de créer un faux sentiment de sécurité.

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

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

    Parce qu’il n’y a pas vraiment besoin de le faire, et parce qu’il faudrait supprimer en prenant le pointeur vers le pointeur plutôt que vers le pointeur.

    delete est principalement utilisé dans les destructeurs, auquel cas la définition d’un membre sur NULL est inutile. Quelques lignes plus tard, à la fermeture } , le membre n’existe plus. Dans les opérateurs d’affectation, une suppression est généralement suivie d’une affectation de toute façon.

    De plus, cela rendrait le code suivant illégal:

     T* const foo = new T; delete foo; 

    Si vous avez un tableau de pointeurs et que votre deuxième action consiste à supprimer le tableau vide, il est inutile de définir chaque valeur sur null lorsque la mémoire est sur le point d’être libérée. Si vous voulez qu’il soit nul, écrivez-lui null 🙂

    C ++ vous permet de définir votre propre opérateur new et delete afin d’utiliser par exemple votre propre allocateur de pool. Si vous faites cela, il est possible d’utiliser new et delete avec des éléments qui ne sont pas ssortingctement des adresses, mais des index dans votre tableau de pool. Dans ce contexte, la valeur de NULL (0) pourrait avoir une signification juridique (en référence au premier élément du pool).
    Ainsi, le fait de supprimer automatiquement la valeur NULL de son argument n’a pas toujours le sens de – définir la valeur sur une valeur non valide. La valeur non valide peut ne pas toujours être NULL.

    Voici une autre raison Supposons que delete définit son argument sur NULL:

     int *foo = new int; int *bar = foo; delete foo; 

    La barre doit-elle être définie sur NULL? Pouvez-vous généraliser cela?

    La philosophie du C ++ est “ne payez que si vous l’utilisez”. Je pense que cela peut répondre à votre question.

    Parfois aussi, vous pouvez avoir votre propre tas qui récupérera de la mémoire supprimée .. ou parfois un pointeur n’appartenant à aucune variable. Ou un pointeur stocké dans quelques variables – il est possible de ne mettre qu’un seul d’entre eux.
    Comme vous pouvez le voir, il y a beaucoup de problèmes et de problèmes possibles.

    La définition automatique du pointeur sur NULL ne résoudrait pas la plupart des problèmes liés à l’utilisation incorrecte du pointeur. Le seul problème qu’il éviterait est d’essayer de le supprimer deux fois. Et si vous appelez une fonction membre sur un tel pointeur? Il se crasherait toujours (en supposant qu’il accède aux variables membres). C ++ ne vous empêche pas d’appeler une fonction quelconque sur les pointeurs NULL, ni du sharepoint vue des performances.

    Je vois des gens donner des réponses étranges à cette question.

    ptr = NULL; Comment une telle déclaration peut-elle provoquer un retard de performance?

    Une autre réponse est que nous pouvons avoir plusieurs pointeurs pointant vers le même emplacement mémoire. Nous pouvons sûrement. Dans ce cas, une opération de suppression sur un seul pointeur ne rendrait que ce pointeur NULL (si le pointeur NULL était supprimé) et l’autre pointeur serait NULL et pointant vers l’emplacement de la mémoire libre.

    La solution à ce problème aurait dû être que l’utilisateur supprime tous les pointeurs pointant vers le même emplacement. En interne, il convient de vérifier si la mémoire est déjà libérée plutôt que libre. Ne faites que le pointeur NULL.

    Stroustrup aurait pu concevoir une suppression pour fonctionner de cette manière. Il pensait que les programmeurs s’en occuperaient. Alors il a ignoré.