Voici un exemple de code que j'ai:
void test()
{
Object1 *obj = new Object1();
.
.
.
delete obj;
}
Je l'exécute dans Visual Studio et il se bloque à la ligne avec 'delete obj;'. N'est-ce pas la manière normale de libérer la mémoire associée à un objet? J'ai réalisé qu'il invoque automatiquement le destructeur ... est-ce normal?
Voici un extrait de code:
if(node->isleaf())
{
vector<string> vec = node->L;
vec.Push_back(node->code);
sort(vec.begin(), vec.end());
Mesh* msh = loadLeaves(vec, node->code);
Simplification smp(msh);
smp.simplifyErrorBased(errorThreshold);
int meshFaceCount = msh->faces.size();
saveLeaves(vec, msh);
delete msh;
}
loadleaves()
est une fonction qui lit un maillage à partir du disque et crée un objet Mesh
et le renvoie. (pensez à vec
et node->code
ne sont que des informations sur le fichier à ouvrir)
Dois-je supprimer la ligne delete msh;
?
N'est-ce pas la manière normale de libérer la mémoire associée à un objet?
C'est une façon courante de gérer la mémoire allouée dynamiquement, mais ce n'est pas une bonne façon de le faire. Ce type de code est fragile car il n'est pas à l'abri des exceptions: si une exception est levée entre le moment où vous créez l'objet et le moment où vous le supprimez, vous perdrez cet objet.
Il est préférable d'utiliser un conteneur de pointeur intelligent, que vous pouvez utiliser pour obtenir une gestion des ressources liée à la portée (il est plus communément appelé l'acquisition des ressources est l'initialisation , ou RAII).
Comme exemple de gestion automatique des ressources:
void test()
{
std::auto_ptr<Object1> obj1(new Object1);
} // The object is automatically deleted when the scope ends.
Selon votre cas d'utilisation, auto_ptr
peut ne pas fournir la sémantique dont vous avez besoin. Dans ce cas, vous pouvez envisager d'utiliser shared_ptr
.
Quant à savoir pourquoi votre programme se bloque lorsque vous supprimez l'objet, vous n'avez pas donné suffisamment de code pour que quiconque puisse répondre à cette question avec certitude.
Votre code utilise en effet la manière normale de créer et de supprimer un objet dynamique. Oui, il est parfaitement normal (et en effet garanti par le standard du langage!) Que delete
appelle le destructeur de l'objet, tout comme new
doit appeler le constructeur.
Si vous n'étiez pas en train d'instancier Object1
directement mais une sous-classe de celle-ci, je vous rappelle que toute classe destinée à être héritée doit avoir un destructeur virtuel (afin que le destructeur de la sous-classe correcte puisse être invoqué dans des cas analogues à celui-ci) - mais si votre exemple de code est en effet représentatif de votre code réel, cela ne peut pas être votre problème actuel - doit être autre chose, peut-être dans le code destructeur que vous ne nous montrez pas, ou une corruption de tas dans le code que vous '' ne s'affiche pas dans cette fonction ou dans celles qu'elle appelle ...?
BTW, si vous allez toujours supprimer l'objet juste avant de quitter la fonction qui l'instancie, il est inutile de rendre cet objet dynamique - déclarez-le simplement comme local (classe de stockage auto
, comme c'est la variable par défaut) de ladite fonction!
N'est-ce pas la manière normale de libérer la mémoire associée à un objet?
Oui, ça l'est.
J'ai réalisé qu'il invoque automatiquement le destructeur ... est-ce normal?
Assurez-vous que vous n'avez pas double suppression votre objet.
s'il se bloque sur la ligne delete
, alors vous avez presque certainement corrompu le tas. Nous aurions besoin de voir plus de code pour diagnostiquer le problème car l'exemple que vous avez présenté ne contient aucune erreur.
Vous avez peut-être un débordement de tampon sur le tas qui a corrompu les structures de tas ou même quelque chose d'aussi simple qu'un "double free" (ou dans le cas c ++ "double delete").
En outre, comme l'a noté The Fuzz, vous pouvez également avoir une erreur dans votre destructeur.
Et oui, il est tout à fait normal et attendu que delete
invoque le destructeur, c'est en fait l'un de ses deux objectifs (appeler destructeur puis libérer de la mémoire).
saveLeaves(vec,msh);
Je suppose qu'il prend le pointeur msh
et le place à l'intérieur de vec
. Puisque msh
n'est qu'un pointeur vers la mémoire, si vous le supprimez, il sera également supprimé à l'intérieur du vecteur.