C++ Tableau de pointeurs: delete ou delete []?
Cosider le code suivant:
class Foo
{
Monster* monsters[6];
Foo()
{
for (int i = 0; i < 6; i++)
{
monsters[i] = new Monster();
}
}
virtual ~Foo();
}
Est-ce le bon destructeur?
ce:
Foo::~Foo()
{
delete [] monsters;
}
ou ceci:
Foo::~Foo()
{
for (int i = 0; i < 6; i++)
{
delete monsters[i];
}
}
J'ai actuellement de la plus haute constructeur et tout fonctionne okey, mais bien sûr je ne peux pas voir si elle arrive à être une fuite...
Personnellement, je pense que la deuxième version est beaucoup plus logique, compte tenu de ce que je suis en train de faire. De toute façon, qu'est-ce que la "bonne" façon de le faire?
Vous devez vous connecter pour publier un commentaire.
delete[] monsters;
Est incorrect, car
monsters
n'est pas un pointeur vers un tableau alloué dynamiquement, il est un tableau de pointeurs. En tant que membre de la classe, il sera automatiquement détruite lors de l'instance de classe est détruit.Votre autres de la mise en œuvre est correcte comme les pointeurs dans le tableau ne sont point à allouée dynamiquement
Monster
objets.Noter que, avec l'allocation de la mémoire de la stratégie que vous voulez probablement pour déclarer votre propre constructeur de copie et de copie opérateur d'affectation, de sorte que non intentionnelle de la copie n'est pas une cause double supprime. (Si vous vous voulez empêcher la copie vous pouvez déclarer comme privés et de ne pas réellement les mettre en œuvre.)
Pour
new
vous devez utiliserdelete
. Pournew[]
utilisationdelete[]
. Votre deuxième variante est correct.La seconde est correcte dans les circonstances (et bien, le moins de mal, de toute façon).
Edit: "moins mauvais", comme dans le code d'origine ne montre aucune bonne raison d'être à l'aide de
new
oudelete
en premier lieu, de sorte que vous devriez probablement utiliser:Le résultat sera plus simple de code et nettoyant de la séparation des responsabilités.
Monster
est un type polymorphe. Dans ce cas, une sorte de pointeur doit être utilisé comme le type de l'élément de lavector
pour permettre le polymorphisme.new
échoue (et lève une exception) lorsque vous essayez de répartir le quatrièmeMonster
dans votre tableau?std::vector<Monster>
sans pointeur est vraiment le plus simple et le "plus C++" de la solution, comme suggéré par Jerry.MonsterDisplayer
s doit être capable de gérer les monstres à partir d'autres sources (pensez à eux comme temporaire des monstres). Nah, ce n'est pas la solution non plus. Merci de penser à ce sujet avec moi, si.vector
n'est probablement pas le meilleur choix du conteneur. En supposant qu'il reste quelque part autour de 6 éléments, unlist
pourrait être un choix raisonnable.std::deque
. Ses règles sur quand les itérateurs sont invalidés sont plus complexes, mais l'accès est presque aussi rapide que dans unvector
.myMonsterCollection
etyourMonsterCollection
) certains de ces pointeurs peuvent être copiés (àMonsterDisplayers
) et ils pourraient passer de ma collection à votre collection et vice versa (en réalité il y a plus de deux emplacements). - Je exécuter une boucle sur le "tableau" pour voir quels monstres souhaitez enregistrer les événements. L'original de la "matrice" est alors vraiment n'a gardé que le "propriétaire". Est-ce un bon modèle?Pour simplifier la answare, regardons le code suivant:
La sortie est:
Destructeur De 1
et puis c'est la plante (Expression: _BLOCK_TYPE_IS_VALID(phead - nBlockUse)).
Nous devons utiliser: delete[] arr; becuse c'est de supprimer l'ensemble du tableau et pas juste une cellule!
essayez d'utiliser delete[] arr; la sortie est:
Destructeur De 10
Destructeur De 9
Destructeur De 8
Destructeur De 7
Destructeur De 6
Destructeur De 5
Destructeur De 4
Destructeur De 3
Destructeur De 2
Destructeur De 1
C'est le même principe pour un tableau de pointeurs:
si nous allons utiliser supprimer arr au lieu de delete[] arr. cela ne supprimera pas l'ensemble de pointeurs dans le tableau => fuite de mémoire du pointeur de la des objets!
delete[] monsters
est certainement mauvais. Mon tas débogueur affiche la sortie suivante:Comme vous pouvez le voir, vous êtes en essayant de libérer avec la forme incorrecte de supprimer (tableau non vs array), et le pointeur 0x22ff38 n'a jamais été retourné par un appel à nouveau. La deuxième version montre le bon de sortie:
De toute façon, je préfère une conception où manuellement la mise en œuvre de l'destructeur n'est pas nécessaire de commencer.
Votre deuxième exemple est correct; vous n'avez pas besoin de supprimer le
monsters
tableau lui-même, juste les différents objets que vous avez créés.Il ferait de sens si ce code était comme ça:
Vous supprimez chaque pointeur individuellement, et vous supprimez l'ensemble de la matrice. Assurez-vous que vous avez défini une bonne destructeur pour les classes étant stockées dans le tableau, sinon vous ne pouvez pas être sûr que les objets sont nettoyés correctement. Assurez-vous que tous vos destructeurs sont virtuels, afin qu'ils se comportent correctement lorsqu'il est utilisé avec l'héritage.