C++: Supprimer un struct?
J'ai une structure qui contient des pointeurs:
struct foo
{
char* f;
int* d;
wchar* m;
}
J'ai un vecteur de partage des pointeurs vers ces structures:
vector<shared_ptr<foo>> vec;
vec
est alloué sur la pile. Quand il passe hors de portée à la fin de la méthode, son destructeur sera appelé. (À droite?) Qui à son tour appeler le destructeur de chaque élément du vecteur. (À droite?) N'appelant delete foo
de supprimer les pointeurs comme foo.f
, ou est-elle vraiment libre de la mémoire dans le tas?
Vous devez vous connecter pour publier un commentaire.
va supprimer la mémoire allouée pour le foo structure, qui comprend les trois pointeurs. Mais la mémoire pointé par les pointeurs seront supprimés si vous implémentez un destructeur explicitement les supprime.
Si vous avez alloué dynamiquement
foo
, par exemple:puis
delete f
va détruire la allouée dynamiquementfoo
objet, y compris les pointeurs qu'il contient, mais pas rien indiqué par les indicateurs, s'ils ne sont en effet au point alloué dynamiquement des objets ou des tableaux d'objets.Si vous avez attribué une allouée dynamiquement
foo
objet (c'est à dire le résultat denew foo
) à unshared_ptr
(en supposant que tr1 ou boost), puis lorsque le derniershared_ptr
se référant à l'objet est hors de portéedelete
sera appelé sur le pointeur à l'origine retourné parnew foo
automatiquement. Vous n'avez pas à le faire manuellement.Si votre objet (
foo
) contient des pointeurs vers les objets alloués dynamiquement qu'il possède (donc le besoin de le libérer à la fin de la durée de vie de lafoo
), alors il est fortement recommandé que vous écrivez un destructeur pour désallouer ces objets dans le bon sens (qui dépendra de la façon dont ils sont affectés).Une fois que vous avez écrit un destructeur, vous devez considérer si vous avez besoin d'écrire un constructeur de copie et de copie assingment de l'opérateur. Comme vous êtes en utilisant un vecteur de pointeurs partagés, vous pouvez décider que vos objets ne doivent pas être copiés. Si oui, vous pouvez déclarer privé et n'a pas besoin de fournir une implémentation.
Vous devez également envisager un ou plusieurs constructeurs de veiller à ce que votre pointeur membres sont initialisées. Si le pointeur de la les membres ne sont jamais initialisé alors si ils ne sont pas affectés au cours de la durée de vie d'un
foo
alors ils ne seront ni nulle, ni point d'un objet valide et c'est probablement à cause d'une erreur dans votre destructeur.Il supprime uniquement les pointeurs.
Il semble que certains terminologiques mixup dans votre question. Destructeur du vecteur appeler les destructeurs pour
shared_ptr
éléments, qui à son tour va effectuer à l'internedelete
sur leur stockées pointeurs (si nécessaire).Appel
delete foo
, oùfoo
est un pointeur versstruct foo
, va appeler le destructeur destruct foo
puis de libérer la mémoire occupée par*foo
.Le destructeur de la ci-dessus
struct foo
ne fait absolument rien. Il est trivial. Si ne vais pas faire de tentatives pour désallouer de la mémoire pointée parstruct foo::f
ou les autres membres. Pourquoi serait-il? Il n'est pas et ne peut pas savoir si cette mémoire doit être libéré.En fait, parce que
struct foo::~foo
est trivial, les compilateurs ne sont normalement pas même essayer de l'appeler.Vous n'appelez pas
delete f
où f est un objet de typefoo
sif
est pile allouée. Vous pouvez aussi ne pas appelerdelete f
sur un segment de mémoire allouée objet de typefoo
si cette adresse est stockée dans un pointeur partagé.shared_ptr
objets appelleradelete
pour vous lors de la dernière référence est libéré.Depuis votre vecteur stocke des pointeurs intelligents, ils tomberont aussi hors de portée lorsque votre vecteur tombe hors de la portée et de la
foo
destructeur sera appelé et associés de la mémoire libérée. La mémoire defoo
est de la taille de 3 pointeurs que. Pas ce que ces pointeurs contiennent.Si les membres de
foo
sont de segment de mémoire allouée, alors vous aurez besoin dedelete
séparément. Par exemple peut-être dans le foo destructeur si la mémoire qu'ils ont point n'est pas partagé entre les objets.Droit.
Droit. Le destructeur de pointeur intelligent.
Il appelle le destructeur de pointeur intelligent, si il n'y a pas plus de références pour que le pointeur de l'objet qu'il contient sera supprimé et son mémoire sera libérée.
Quand il [cev] passe hors de portée à la fin de la méthode, son destructeur sera appelé. (À droite?)
Corriger
Qui va à son tour appeler le destructeur de chaque élément du vecteur. (À droite?)
Correct, cela permettra de supprimer les shared_ptr éléments dans le conteneur, et si ils sont les derniers à aussi les articles qu'ils sont partage.
N'appelant supprimer foo ...?
Vous ne pouvez pas supprimer foo, c'est une struct. Vous pouvez supprimer une instance de foo.
L'appel de supprimer appelle le destructeur et de libérer de la mémoire pour la struct foo.
Ne les foo destructeur de supprimer les pointeurs comme les foo::f, ou est-elle vraiment libre de la mémoire dans le tas?
Cela dépend de la destructo, dans ce cas, vous avez un destructeur par défaut et ainsi de...
Non, Dans l'exemple de code suivant vous pouvez voir quelques-unes des raisons pour lesquelles le destructeur par défaut associée à toto ne peut pas le nettoyage de toute pointeur de visée automatique des éléments.