Est-il possible de supprimer un non-nouvel objet?
J'ai un objet avec un vecteur de pointeurs vers d'autres objets, quelque chose comme ceci:
class Object {
...
vector<Object*> objlist;
...
};
Maintenant, les Objets seront ajoutés à la liste dans les deux de ces façons:
Object obj;
obj.objlist.push_back(new Object);
et
Object name;
Object* anon = &name;
obj.objlist.push_back(anon);
Si un faire un destructeur qui est tout simplement
~Object {
for (int i = 0; i < objlist.size(); i++) {
delete objlist[i];
objlist[i] = NULL;
}
}
Aura-t-il des conséquences négatives en termes d'lorsqu'il tente de supprimer un objet qui n'a pas été créé avec de nouvelles?
Je sais qu'il pourrait être mieux avec un itérateur, mais
objlist
était à l'origine et tableau et je n'ai pas eu le temps de changer la boucle.OriginalL'auteur | 2010-12-04
Vous devez vous connecter pour publier un commentaire.
Oui, il y aura les effets indésirables.
Vous ne devez pas
delete
un objet qui n'a pas été alloué avecnew
. Si l'objet a été alloué sur la pile, votre compilateur a déjà généré un appel à son destructeur à la fin de son champ d'application. Cela signifie que vous devrez appeler le destructeur deux fois, avec potentiellement des effets très mauvais.D'ailleurs appelé le destructeur deux fois, vous pourrez également tenter de libérer un bloc de mémoire qui a été jamais alloué. Le
new
opérateur sans doute met les objets sur le tas;delete
s'attend à trouver l'objet dans la même région que lenew
opérateur met. Cependant, votre objet qui n'a pas été alloué avecnew
vie sur la pile. Ce sera très probablement le plantage de votre programme (si ce n'est pas déjà crash après l'appel au destructeur une seconde fois).Vous obtiendrez également dans le pétrin si votre
Object
sur le tas vit plus longtemps que votreObject
sur la pile: vous aurez un bancales référence à quelque part sur la pile, et vous obtiendrez des résultats incorrects/crash la prochaine fois que vous y accédez.La règle générale je vois, c'est que des trucs qui vivent sur la pile peut faire référence à des trucs qui vit sur le tas, mais les choses sur le tas doit pas référence à des trucs sur la pile en raison de la très forte chances qu'ils dureront plus longtemps que la pile d'objets. Et des pointeurs vers les deux ne doivent pas être mélangés ensemble.
Il n'existe pas de fonctionnalité pour vous y aider. Une fois que vous avez un pointeur, vous ne pouvez pas (sans plate-forme à charge de la magie noire/activités dangereuses) de savoir si elle pointe vers quelque part sur la pile ou sur le tas. C'est généralement une mauvaise idée de mélanger des objets qui vivent sur la pile et les objets qui vivent sur le tas. Votre meilleur pari serait d'utiliser
new
pour tous.Ce que vous êtes censé faire est de faire le même code responsable de la
new
ing pour ledelete
ing. Pour les conteneurs, vous laissez le récipient de faire les deux, en ayant explicitement copie tout ce qui est mis dans le conteneur. (Il vous protège également contre le code appelant de laisser la pointe-au chose tomber hors de portée.) Mais ne pas écrire vos propres contenants de toute façon; la bibliothèque standard fournit ce dont vous avez besoin.Ithink c'est une bonne réponse ! Mais ce qui me manque c'est qu'il est possible de prendre en charge une classe de gestion de la mémoire (tous les opérateurs new et delete),ce qui peut rendre possible de faire appel à supprimer dans chaque pointeur. (ne pensez pas que vous devriez bien)
OriginalL'auteur zneak
Non, vous ne pouvez
delete
ce que vousnew
edLorsque le nom est hors de portée, vous aurez un pointeur non valide dans votre vecteur.
OriginalL'auteur Dark Falcon
Ce que vous êtes en train de demander est de savoir si il est sûr de supprimer un objet n'est pas affecté par
new
par le biais de ladelete
opérateur, et si oui, pourquoi?Malheureusement, c'est obscurci par d'autres problèmes dans votre code. Comme mentionné, lorsque nom est hors de portée, vous allez finir avec un pointeur non valide.
Voir zneak réponse pour pourquoi votre question initiale ne risque pas d'entraîner un fonctionnement sûr, et pourquoi le champ d'application de nom en fait des questions.
OriginalL'auteur MrGomez
Cela ne fonctionnera pas si vous
delete
un objet qui n'était pas affecté parnew
vous avez enfreint les règles ou lesdelete
opérateur.Si vous avez besoin d'avoir votre vecteur de stocker des objets qui peuvent ou peuvent ne pas avoir besoin d'être supprimé, vous aurez besoin de garder une trace de ce en quelque sorte. Une option est d'utiliser un pointeur intelligent qui garde une trace de savoir si le fait d'objet est dynamique ou pas. Par exemple,
shared_ptr<>
vous permet de spécifier un deallocator objet lors de la construction de lashard_ptr<>
et que les docs mention:Cependant, vous devez toujours être prudent lors du passage de pointeurs vers des variables automatiques - si le vecteur de la durée de vie est plus longue que la durée de vie de la variable ensuite, il sera fait référence à ordures à un certain point.
OriginalL'auteur Michael Burr