Comment détecter si un pointeur a été supprimé et le supprimer en toute sécurité?
Dans C++ Comment décider ou de savoir si un pointeur a été supprimé avant??
quand j'ai essayé de supprimer un pointeur qui a été supprimé précédemment dans une autre partie du code qu'il a déclenché une exception qui ne peut être géré.
Je me demandais si il existe un moyen de vérifier ou d'essayer de supprimer le pointeur ? toute référence à propos de la mémoire avancée des opérations.
aussi je veux à la maîtrise de l'onu-exceptions traitées de pointeurs et de l'accès protégé ou d'accès est une violation ,... ce genre d'erreur.
merci pour ceux qui donnent un peu de leurs connaissances et de leur temps pour aider d'autres personnes et de partager leurs prestations
Mise à jour
Les grands conseils de beaucoup de développeurs c++ modernes de la communauté est - Utilisation des pointeurs intelligents ou d'essayer d'éviter l'utilisation de matières premières de pointeurs. Mais pour jeter de la sécurité et de l'assurance libre de la mémoire (ISO_CPP_FAQ) et bien sûr, si vous voulez éviter les petits frais généraux de l'utilisation des pointeurs intelligents[peut ne pas être perceptible toujours, mais ils ont une surcharge] vous pouvez écrire votre propre méthodes qui traitent avec des pointeurs [*] - ce n'est pas général.
Préférez toujours des pointeurs intelligents à raw pointeurs.
Dans "Going Native" en 2013 d'un commun avis a été donné - ne Jamais utiliser des pointeurs.
source d'informationauteur ahmedsafan86
Vous devez vous connecter pour publier un commentaire.
Il peut y avoir trois solutions. Vous pouvez choisir un en fonction de l'effort de rapport qualité/vous souhaitez réaliser:
Élégante et la plus correcte de la solution:
Utilisation pointeurs intelligents et vous n'avez pas manuellement appel
delete
jamais de nouveau. C'est le meilleur moyen possible de surmonter ce problème. Il utilise le principe de la RAII qui fonctionne parfaitement pour un langage tel que le C++ qui ne dispose pas d'un garbage collector.Moins élégant mais efficace solution:
Affecter le pointeur de
NULL
après la suppression. L'appel dedelete
sur unNULL
pointeur est un no-op de sorte qu'il supprime la nécessité d'avoir cette extraNULL
vérifier mais c'est peut - cacher quelques problèmes au lieu de les rendre visibles.Moins élégant mais plus la bonne solution:
Traquer tous les multiples
delete
problèmes en laissant votre plantage du programme. Vous pourriez aussi bien utiliser de la mémoire de l'analyseur de programmes comme valgrind et puis réparer votre code pour éviter tous ces problèmes.C'est une bonne question, mais l'une des vérités fondamentales de travail dans un manuellement la mémoire gestion de l'environnement (comme le C/C++ et ses cousins) est qu'il n'y a pas de bonne façon de regarder un pointeur après le fait et en demandant s'il est valide-- une fois qu'il est devenu invalide, il est parti, et en la regardant, il a tendance à exploser. Votre travail est de faire en sorte qu'il n'est jamais supprimé ou libéré plus d'une fois, et jamais utilisés après cette date.
Certainement regarder les pointeurs intelligents, qui ont été inventées pour rendre la vie des programmeurs plus facile dans ces circonstances. (La méthode la plus traditionnelle est d'être prudent, de ne pas le visser en place, et puis peut-être affecter NULL le pointeur lorsque vous savez qu'il a été effacé, comme Alok dit.)
La langue standard n'offre aucun moyen juridique pour déterminer si l'arbitraire d'un pointeur est valide ou pas.
Il y a un moyen, mais il est très compilateur/OS. Vous pouvez soit le crochet dans le gestionnaire de mémoire ou de le remplacer par votre propre et de fournir une fonction dédiée pour pointeur de la validation. Il est peut-être pas très facile à faire, cependant. Et vous n'avez pas vraiment besoin de s'appuyer sur cette fonctionnalité, si la performance est critique.
Le pointeur ne vais pas vous dire quoi que ce soit. Votre dessin devrait: si
vous êtes à l'aide de l'allocation dynamique, c'est normalement parce que votre
l'application nécessite l'objet d'une vie, donc
vous savez quand vous supprimer correctement l'objet. Si l'objet est
copiable, ou a une durée de vie qui correspond à portée, vous
ne pas (normalement) à allouer de façon dynamique.
Il y a, bien sûr, des exceptions à très faible niveau de code si
vous êtes à la mise en œuvre de quelque chose comme
std::vector
, vous aurezd'utiliser une sorte d'allocation dynamique, parce que la taille n'est pas
connu au moment de la compilation. Mais cette répartition ne devrait pas échapper;
il est de la responsabilité du faible niveau de classe permettant de gérer la
de la mémoire.
Enfin, les dépassements de la mémoire tampon, l'accès à déjà supprimé de la mémoire, et
les autres sont un comportement indéfini. Ils ne sont pas, en général,
une exception, et il n'y a pas un moyen générique de
la manipulation. (Vous peut généralement de prendre des dispositions pour obtenir un signal lorsque
de telles choses se produisent, mais il y a tellement peu de choses que vous pouvez faire à partir d'un
gestionnaire de signal, ce n'est pas vraiment aider beaucoup.) En général,
ce que vous voulez est pour le planter le programme, car vous ne savez pas
dans quel état elle est. Dans les rares cas où ce n'est pas le
cas, vous devez vous rabattre sur la mise en œuvre définies
les extensions, si elles existent. Si vous compilez avec l'
/EHa
option avec VC++, par exemple, ce qui serait normalement un crash
sera coverted dans une des exceptions C++. Mais c'est un VC++
d'extension, et vous ne savez toujours pas l'état général de la
programme lorsque cela se produit. Si c'est parce que vous avez corrompu l'
l'espace libre de l'arène, il n'y a probablement pas beaucoup que vous pouvez faire, même si
vous intercepter l'exception (et il ya une bonne chance que vous allez obtenir
une autre exception à partir d'un destructeur d'essayer de libérer de la mémoire lors de l'
vous détendre de la pile).
utilisation
shared_ptr<>
etshared_array<>
n'oubliez passhared_ptr<>
peut être utilisé pour gérer l'allocation de la mémoire pour un tableau que s'il Deleter est fourni, sinon utilisershared_array<>
pour gérer vos tableaux//ok si
est fourni
Pointeur intelligent sont un meilleur choix pour éviter de tels problèmes (mais vous devez avoir une compréhension complète avant de les utiliser aussi), mais je voudrais mentionner les limites de performances associés avec des pointeurs Intelligents, la raison est qu'ils utilisent habituellement des opérations atomiques par exemple InterlockedIncrement dans l'API Win32 pour le comptage de référence. Ces fonctions sont significativement plus lente que la simple arithmétique entière. Je ne suis pas sûr si peu de performances acceptables dans votre cas ou pas.
Ce que je fais habituellement est (donc je n'ai pas à passer plusieurs jours plus tard pour déboguer les méchants bugs), je passe beaucoup de temps sur le design, et de la durée de vie des objets, avant de déménager pour le codage réel, comme je l'ai supprimé de la mémoire-je définir spécifiquement le pointeur est NULL, il est de bonne pratique pour autant que je pense. De nouveau, peut-être la vraie solution est de passer plus de temps sur la détermination des dépendances et de l'objet de la vie du temps avant de passer!
Je sais que ce fil est vieux. Mais si quelqu'un lit ceci, il faut savoir à propos de unique_ptr. shared_ptr a en effet une surcharge. Le compteur est stocké sur le tas. Chaque fois que le compteur est accessible, il y a un risque d'un cache de processeur incompatibilité. unique_ptr Est plus limitée, mais n'a pas de surcharge en comparaison à la plaine de pointeurs. Ma suggestion est de préférer unique_ptr plus de shared_ptr lorsque vous n'avez pas besoin de comptage de référence.
Une autre remarque importante est que unique_ptr fonctionne bien avec les tableaux.
Si je me souviens bien c'est aussi vrai pour les shared_ptr depuis C++17.