131 votes

Que fait-il Visual Studio avec un pointeur supprimé et pourquoi ?

C++ livre, j'ai lu stipule que, lorsqu'un lien est supprimé à l'aide de l' delete opérateur de la mémoire à l'endroit qu'il désigne est "libéré" et il peut être remplacé. Il stipule également que le pointeur de la continuent de pointer vers le même endroit jusqu'à ce qu'il est réaffecté ou un ensemble d' NULL.

Dans Visual Studio 2012; cependant, cela ne semble pas être le cas!

Exemple:

#include <iostream>

using namespace std;

int main()
{
    int* ptr = new int;
    cout << "ptr = " << ptr << endl;
    delete ptr;
    cout << "ptr = " << ptr << endl;

    system("pause");

    return 0;
}

Quand j'ai compiler et exécuter ce programme, j'obtiens le résultat suivant:

ptr = 0050BC10
ptr = 00008123
Press any key to continue....

Clairement l'adresse que le pointeur pointe vers des changements lors de la supprimer est appelé!

Pourquoi est-ce arrivé? Est ce que cela a quelque chose à faire avec Visual Studio?

Et si supprimer pouvez changer l'adresse qu'il désigne de toute façon, pourquoi ne pas supprimer automatiquement le pointeur à l' NULL au lieu d'une adresse au hasard???

175voto

tjwrona1992 Points 2566

J'ai remarqué que l'adresse stockée dans ptr était toujours en cours remplacé par 00008123...

Cela semblait bizarre, donc j'ai fait un peu de creuser et trouvé ce blog Microsoft post contenant une section pour discuter de "Automatisé pointeur de nettoyage lors de la suppression d'objets C++".

...vérifie la valeur NULL est un code commun construire du sens d'une case NULL, combiné avec l'utilisation de la valeur NULL comme une désinfection de valeur pourrait fortuitement en cacher une véritable mémoire de problème de sécurité dont la cause n'a vraiment besoin d'adressage.

Pour cette raison, nous avons choisi 0x8123 comme un nettoyage de la valeur – à partir d'un système d'exploitation point de vue c'est dans la même page de la mémoire que l'adresse zéro (NUL), mais une violation d'accès à 0x8123 résistera mieux pour le développeur comme ayant besoin de plus d'attention.

Non seulement il expliquer ce que Visual Studio ne avec le pointeur après il est supprimé, il répond aussi pourquoi ils ont choisi de ne PAS définir d' NULL automatiquement!


Cette "fonctionnalité" est activé dans le cadre de la "SDL contrôles". Pour l'activer/la désactiver, allez à: PROJET -> Propriétés -> Propriétés de Configuration -> C/C++ -> Général -> SDL vérifie

Pour confirmer cela...

La modification de ce paramètre et en relançant le même code produit la sortie suivante:

ptr = 007CBC10
ptr = 007CBC10

la "fonctionnalité" est entre guillemets car dans le cas où vous avez deux pointeurs vers le même endroit, en appelant supprimer ne désinfecter l'UN d'entre eux. L'autre sera laissé pointant vers l'emplacement non valide.

Visual Studio peut vous mettre en place pour une situation délicate par l'absence de documents de cette faille dans sa conception.

30voto

Hans Passant Points 475940

Vous voyez les effets secondaires de l' /sdl option de compilation. Activée par défaut pour les VS2015 projets, il permet à des contrôles de sécurité supplémentaires au-delà de celles prévues par /gs. Utiliser le Projet > Propriétés > C/C++ > Général > SDL vérifie le réglage à modifier.

Citant l' article MSDN:

  • Effectue limitée pointeur de la désinfection. Dans les expressions qui n'impliquent pas de déréférence et des types qui n'ont pas défini par l'utilisateur destructeur, pointeur références sont définies à un non-valide l'adresse après un appel à supprimer. Cela contribue à empêcher la réutilisation de vieux pointeur de références.

Ne gardez à l'esprit que la définition de supprimé les pointeurs à NULL est une mauvaise pratique lorsque vous utilisez la MSVC. Il va à l'encontre de l'aide que vous obtenez à partir à la fois le Débogage et de Tas ce /sdl option, vous pouvez détecter n'est plus valide gratuit/supprimer des appels dans votre programme.

19voto

R Sahu Points 24027

Il stipule également que le pointeur de la continuent de pointer vers le même endroit jusqu'à ce qu'il est, d'une réaffectation ou la valeur NULL.

C'est certainement des informations trompeuses.

Clairement l'adresse que le pointeur pointe vers des changements lors de la supprimer est appelé!

Pourquoi est-ce arrivé? Est ce que cela a quelque chose à faire avec Visual Studio?

C'est clairement dans le langage de spécifications. ptr n'est pas valide après l'appel à delete. À l'aide de ptr après qu'il a été deleted est la cause d'un comportement indéfini. Ne pas le faire. L'environnement d'exécution est libre de faire ce qu'il veut avec ptr après l'appel à delete.

Et si supprimer pouvez changer l'adresse qu'il désigne de toute façon, pourquoi ne pas supprimer automatiquement le pointeur à NULL à la place d'une adresse au hasard???

La modification de la valeur du pointeur de la souris à n'importe quel valeur est conforme à la spécification du langage. Jusqu'à changer NULL, je dirais, ce serait mauvais. Le programme permettrait d'avoir un comportement plus sain d'esprit, si la valeur du pointeur de la souris ont été mis à NULL. Cependant, vous pouvez masquer le problème. Lorsque le programme est compilé avec différents paramètres d'optimisation ou porté à un environnement différent, le problème susceptible d'apparaître au moment le plus inopportun.

10voto

Giorgi Points 4620
delete ptr;
cout << "ptr = " << ptr << endl;

En général même de la lecture (comme vous le faites ci-dessus, note: ceci est différent de déréférencement) les valeurs des pointeurs invalides (pointeur devient invalide par exemple lorsque vous delete ) est définie par l'implémentation du comportement. Cela a été introduit dans CWG #1438. Voir aussi ici.

Veuillez noter que, avant que la lecture des valeurs de pointeurs invalides est un comportement indéterminé, donc ce que vous avez ci-dessus serait un comportement indéterminé, ce qui signifie que tout peut arriver.

1voto

SergeyA Points 2159

Je crois, vous exécutez une sorte de mode de débogage et VS tente de peretochki votre pointeur à certains endroit connu, de sorte que toute nouvelle tentative de déréférencement il pourrait être tracée et signalés. Essayez de compiler/exécuter le même programme en mode release.

Les pointeurs sont généralement pas modifiée à l'intérieur de delete pour des raisons d'efficacité et pour éviter de donner une fausse idée de la sécurité. Réglage de supprimer le pointeur à valeur prédéfinie, ne servira à rien dans la plupart des scénarios complexes, puisque le pointeur être supprimées peuvent être un seul des plusieurs pointant vers cet emplacement.

Comme une question de fait, plus j'y pense, plus je trouve que VS est la faute quand le faire, comme d'habitude. Que faire si le pointeur est const? Est-il toujours vais le changer?

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