2010-01-18 13 views
2

J'ai créé une classe qui inclut une liste chaînée et cette classe doit avoir un destructeur pour supprimer la liste chaînée, que j'ai inclus cependant parce que la méthode delete elle-même appelle le destructeur que je trouve dans un situation d'appel récursive infinie.appel récursif involontaire dans destructeur

Voici le code: -

PolynomialNode::~PolynomialNode() 
{ 
    /*PolynomialNode* current_node_ptr = link; 
    PolynomialNode* header_ptr = link; 
    int index = 0; 
    if(link != NULL) 
    { 
     while(current_node_ptr != NULL) 
     { 
      index++; 
      current_node_ptr = current_node_ptr->get_link(); 

     } 

     delete_nodes(&header_ptr, 0, index); 
    } */ 
    PolynomialNode* current_node_ptr = link; 
    PolynomialNode* copy_ptr; 
    while(current_node_ptr != NULL) 

    { 
     copy_ptr = current_node_ptr->get_link(); 
     current_node_ptr->set_link(NULL); 
     delete current_node_ptr; 
     current_node_ptr = copy_ptr; 
    } 
} 

Remarque J'ai essayé cela avec un appel récursif - intentionnel pour la suppression de la liste, et j'ai toujours le même problème.

Toute aide serait grandement appréciée. NB: Je sais que c'est un appel récursif car lorsque je parcours le débogueur, je peux le voir se produire.

+0

connexes: http://stackoverflow.com/questions/1861912/should-delete-this-be-called-from-within-a -member-method – jldupont

+0

Je ne vois pas comment cela donnera une récursion infinie - comme 'set_link' fait ce qu'il dit, chaque appel destructeur récursif devrait retourner sans plus de récursivité. –

+0

L'appel resursive se produit lorsque vous essayez de supprimer un pointeur vers une liste liée, c'est-à-dire après la commande delete. Non, je ne pensais pas que cela finirait par être récursif mais quand j'utilise le débogueur, vous pouvez le voir. – hairyyak

Répondre

2

Ajoutez cette ligne dans la boucle while, avant de supprimer:

if (current_node_ptr == this) continue; 

Cela vous permettra d'éviter récursion, en sautant la destruction du nœud qui appelle. Cependant, vous devriez vous demander pourquoi diable est-ce arrivé en premier lieu. Je ne peux pas répondre à cette question, parce que je ne vois pas le reste du code.

Note: ce qui ne va pas à moins que vous avez un lien circulaire, dans le cas dont ce serait une conception valable, aussi longtemps que vous sautez la suppression this.

+2

'==' sûrement? :) – Skurmedel

+0

== semble plus jolie – Dewfy

+0

@Skurmedel, @Dewfy: Lol, cela vient de répondre aux questions C++ tout en travaillant sur le code Pascal xD, merci! –

11

en supposant link est le pointeur à l'autre PolynomialNode, simplement

PolynomialNode::~PolynomialNode() 
{ 
    delete link; 
} 

fera la bonne chose récursive. Cependant, une meilleure solution pourrait consister à conserver votre boucle while() mais à la retirer du noeud au destructeur d'une classe distincte représentant la liste liée dans son ensemble.

+1

Ou même utilisez std :: list (ou std :: vector, puisque std :: list est rarement une meilleure option) ... –

+1

Si c'est une liste cyclique, vous allez faire un blowup spectaculaire. Aussi, si c'est plus de nœuds que la profondeur récursive maximale du compilateur, vous aurez un autre blowup spectaculaire: P –

+0

J'ai essayé ceci et cela a fonctionné donc GRAND merci. – hairyyak

1

lien En supposant est le pointeur à l'autre PolynomialNode, simplement

if(this->link != NULL) delete this->link; 
+0

Oui, c'est fondamentalement la même approche que Moonshadow alors merci. – hairyyak