2010-04-17 5 views
3

J'ai un problème avec delete et destructor (je suis sûr que je fais une erreur stupide ici, mais je n'ai pas encore réussi à le comprendre).C++ supprimer ne fonctionne pas?

Lorsque j'interviens dans le destructeur et que j'essaie d'appeler la suppression sur un pointeur, le message s'affiche "Impossible d'accéder à la mémoire à l'adresse une adresse."

Le code correspondant est:

/* 
* Removes the front item of the linked list and returns the value stored 
* in that node. 
* 
* TODO - Throws an exception if the list is empty 
*/ 
std::string LinkedList::RemoveFront() 
{ 
    LinkedListNode *n = pHead->GetNext(); // the node we are removing 
    std::string rtnData = n->GetData(); // the data to return 

    // un-hook the node from the linked list 
    pHead->SetNext(n->GetNext()); 
    n->GetNext()->SetPrev(pHead); 

    // delete the node 
    delete n; 
    n=0; 

    size--; 
    return rtnData; 
} 

et

/* 
* Destructor for a linked node. 
* 
* Deletes all the dynamically allocated memory, and sets those pointers to 0. 
*/ 
LinkedListNode::~LinkedListNode() 
{ 
    delete pNext; // This is where the error pops up 
    delete pPrev; 
    pNext=0; 
    pPrev=0; 
} 

Répondre

5

Il semble que vous supprimez les nœuds suivants et précédents de la liste de la destructor. Ce qui, si pNext et pPrev sont LinkedListNode*, signifie que vous supprimez récursive toute la liste :-(

Essayez ceci:

std::string LinkedList::RemoveFront() 
{ 
    LinkedListNode *n = pHead->GetNext(); // the node we are removing 
    std::string rtnData = n->GetData(); // the data to return 

    // un-hook the node from the linked list 
    pHead->SetNext(n->GetNext()); 
    n->GetNext()->SetPrev(pHead); 

    n->SetNext(0); 
    n->SetPrev(0); 
    // delete the node 
    delete n; 
    n=0; 

    size--; 
    return rtnData; 
} 

LinkedListNode::~LinkedListNode() 
{ 
} 

(En fait, vous ne devez même pas réinitialiser les prev et pointeurs suivants à 0 étant donné que vous allez supprimer le noeud de toute façon, j'ai laissé ces instructions car elles ont au moins mis le noeud dans un état cohérent, ce qui est une bonne idée en général. stratégie et décidez de stocker les nœuds inutilisés pour une réutilisation ultérieure.)

+0

Les nœuds suivants et précédents stockés dans le nœud actuel (chaque nœud contient des données de chaîne, et un pointeur vers les nœuds suivant et précédent dans la liste). C'est le comportement souhaité, car nous avons décroché ce nœud de la liste chaînée, et maintenant je veux retourner toute la mémoire dynamiquement allouée EDIT - attendez, je pense voir ce que vous dites .. – vimalloc

+0

@kyeana: vous ne voulez que retourner la mémoire associée au seul nœud que vous supprimez –

+3

C'est pire que cela - cela effacera en fait jusqu'à la fin de la liste (récursif à la première suppression) et ensuite tentera de supprimer l'avant-dernier nœud de nouveau à l'intérieur du destructeur du dernier nœud, ce qui est probablement le cas de l'accident. Si X, Y et Z sont les trois derniers nœuds, ~ X supprime Y, ~ Y supprime Z, et ~ Z supprime à nouveau Y. –

1

Il semble que votre LinkedListNode supprime ses voisins, donc quand vous supprimez un nœud, il continue à détruire la liste entière - notez que vous ne définissez pas pNext et pPrev à NULL lorsque vous supprimez votre nœud.

également votre LinkedListNode destructor est problématique même dans le cas où vous voulez la liste complète à détruire: ayant à la fois delete pNext et delete pPrev conduira à plusieurs appels du même destructor (et je pense que finalement un débordement de pile).

+0

oh mon dieu ... le noeud 2 supprime les noeuds 1 et 3, qui essaient tous les deux de supprimer le noeud 2, qui supprime deux fois les noeuds 1 et 3, puis le noeud 2 est effacé quatre fois, ... –

0

En fait, vous ne devriez pas jouer avec des voisins dans un nœud. C'est à faire à la classe de la liste - connectez-les correctement. Dans le destructeur vous pouvez les mettre à null, mais à moins que vous ayez alloué dynamiquement autre chose - vous n'avez pas besoin d'appeler delete