Question

Je suis étudiant en informatique avec la tâche de créer une structure de données dynamique, listes listes. Je travaille actuellement sur une liste individuelle et j'ai réussi à construire avec succès les fonctionnalités pour ajouter, supprimer et vider toutes les données de nœud.

Cependant, en se souvenant que mon conférencier de «programmation avancée» a déclaré que afin d'éviter la confusion et d'autres problèmes, lors de la suppression des nœuds d'une liste ou de la libération de la mémoire d'un objet, vous devriez que cela se produise à l'intérieur de son déconstructeur. Alors j'ai déménagé:

delete[] _del;

Ce qui a bien fonctionné et l'a déplacé vers le déconstructeur des nœuds:

#include "Node.h"

// Node.cpp

Node::Node(const int &inData, const int &inId)
{
    _id = inId;
    _data = inData;
    nextNode = NULL;
}

// Deconstructor to delete the node when using List.Del()
Node::~Node()
{
    delete[] this;
}

Dans ma liste, le déconstructeur du nœud est appelé via un pointeur comme ça:

_del->~Node();

Ce qui me donne une erreur d'assurance. Je suppose que c'est mon utilisation de «ceci» dans le déconstructeur du nœud?

Merci pour votre temps.

Était-ce utile?

La solution

Tout d'abord, vous ne devez pas appeler un destructeur d'objets directement, sauf si vous écrivez un allocateur et que vous utilisez le placement nouveau lors de la création. Deuxièmement, tu devrais delete et pas delete[] Sauf si vous avez également utilisé new[]. Et enfin, delete this est une mauvaise habitude, mais légale selon la norme. Pourquoi tu n'appelles pas juste delete theNode Au lieu de tout cela?

EDIT: Aborder certains commentaires / questions supplémentaires.

Pour allouer une seule instance sur un tas, vous utilisez theNode = new Node. Le pointeur retourné doit être libéré avec delete theNode. Appeler New Will allouer la mémoire et ensuite appeler Node::Node(), le constructeur, afin qu'il puisse configurer son état interne. Appeler Delete appellera Node::~Node() puis libérer la mémoire allouée. Le destructeur est responsable du nettoyage de tout ce que le nœud utilise, mais pas la mémoire utilisée par le nœud lui-même.

Pour allouer un tableau de nœuds, vous utilisez theNodes = new Node[10];. Vous les supprimez avec delete[] theNodes. Mélanger le nouveau / supprimer avec un nouveau comportement [] / delete [] est un comportement non défini.

Placement New est une méthode où vous souhaitez construire un objet dans Déjà de mémoire allouée. Dans ce cas, vous avez la seule bonne raison d'appeler un destructeur directement, vous voulez déconstruire un objet (aka le laisser se nettoyer) sans pour autant Libérant également la mémoire allouée pour cela.

Appel delete this est légal dans par exemple un Suicide() fonction, tant que vous ne faites pas référence à "ceci" ou à aucun membre de l'instance supprimée après l'appel à delete this. Il s'agit d'une technique valide, par exemple, dans les objets comptés de référence, mais est souvent considéré comme quelque chose que vous devez éviter, sauf si vous en avez vraiment besoin.

La bonne solution pour vous est assez simple, où vous appelez maintenant ~Node, appelez simplement delete theNode Au lieu.

Autres conseils

Comment un objet est-il supprimé à l'intérieur de son déconstructeur, correctement?

Ce n'est pas. Un destructeur nettoie les ressources appartenant à un objet, pas l'objet lui-même.

Vous devriez supprimer l'utilisation de Supprimer et tout ce qui a alloué le nœud (votre classe de liste?) Il vaut mieux être responsable de le traiter. La façon la plus simple de le faire est d'avoir exactement un point dans votre classe de liste qui alloue et ajoute des nœuds à la liste, et exactement un point qui supprime et traite les nœuds (la méthode del mentionnée). Ayez à plusieurs reprises votre classe de classe de la classe de la classe jusqu'à ce que la liste soit vide.

Node::~Node()
{
    delete[] this;
}

Comportement non défini. Je vais probablement écraser votre programme!

Au fait, il y a une différence entre delete this et delete[] this. Alors que delete this pourrait être ok parfois, mais delete[] this n'est pas comme this ne peut jamais être alloué en utilisant new[]. Ce n'est pas un pointeur vers un tableau. C'est un pointeur vers un objet!

Comme Une réponse précédente suggère que votre déconstructrice est un comportement non défini. Pour la raison suivante:

Lorsque

delete[] _del;

est exécuté. Il tente de supprimer le même objet, que vous essayez de supprimer dans son déconstructeur

delete[] this;

Ce que le texte de votre cours signifie, c'est que si vous souhaitez effacer tout objet associé à la suppression, qui devrait également être libéré dans le déconstructeur de cet objet. Par exemple, si l'ID et / ou les données étaient des pointeurs:

Node::~Node()
{
   delete _id;
   delete _data;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top