2017-01-26 1 views
-2

J'ai essayé de rechercher le sujet mais tous les threads que j'ai trouvés utilisés pendant les boucles. Cependant, je voudrais faire récursive:destructeur récursif pour liste chaînée

template <typename S> 
struct node { 
    S data; 
    node<S> * next; 
}; 

c'est la fonction que j'invoque dans le destructor (passer la tête en tant que paramètre) de la liste chaînée:

void destroy(node<T> * n) { 
    if(n->next != NULL){ 
     destroy(n->next); 
    } 
    delete n; 
} 

Malheureusement, le résultat est un erreur de segmentation. Quelqu'un peut-il m'aider?

Edit: code complet

#include <iostream> 

using namespace std; 


template <typename T> 
class List { 
    private: 

    template <typename S> 
    struct node { 
     S data; 
     node<S> * next; 
    }; 

    node<T> * first; 

    node<T> * get_last_p() { 
     if(first != NULL){ 
      return get_last(first); 
     } 
     return NULL; 
    } 

    node<T> * get_last(node<T> * n) { 
     if(n->next != NULL) { 
      return get_last(n->next); 
     } else { 
      return n; 
     } 
     return NULL; 
    } 

    void destroy(node<T> * n) { 
     if(n->next != NULL){ 
      destroy(n->next); 
     } 
     delete n; 
    } 


    public: 

    List() {first->next = 0;} 
    ~List() {destroy(first);} 

    void add(T element) { 
     node<T> * new_element = new node<T>; 
     new_element->data = element; 
     if(first == NULL){ 
      first = new_element; 
     } else { 
      get_last_p()->next = new_element; 
     } 
    } 

    T get_last() { 
     return get_last_p()->data; 
    } 

    T get_first() { 
     return first->data; 
    } 

}; 
+2

Êtes-vous sûr que 'n' n'est jamais nul? – KABoissonneault

+1

http://stackoverflow.com/help/mcve – xaxxon

+0

Si vous ne savez pas où se situe le problème, vous ne savez pas où le problème ne se situe pas. Postez votre code. – xaxxon

Répondre

2

D'après ce que je peux voir, dans le constructeur de List, first n'est pas initialisé, et est ensuite accessible immédiatement. C'est un comportement indéfini. Même si first était en quelque sorte initialisé à null d'une manière non fiable, et que first->next = 0; ne planterait pas d'une manière ou d'une autre, vous échoueriez également dans destroy de votre destructeur, puisque destroy suppose que son argument original n'est pas nul.

Je suppose que vous vouliez dire à List() : first{ new node{} } { first->next = nullptr; }

Si first ne vise pas à contenir une valeur, alors vous allez avoir à factoriser votre code d'abord initialiser first null - il n'y a pas de travail autour - et gérer le cas où first est explicitement nulle dans tout votre code. Vous ne pouvez pas affecter first->next d'un pointeur nul, invalide ou non défini.

+0

lorsque j'initialise déjà 'first' dans le constructeur, comment puis-je vérifier dans ma fonction 'add' si 'first' contient une valeur réelle? – cmplx96

+0

Édité pour offrir une solution qui correspond plus étroitement à ce que vous vouliez faire – KABoissonneault

+0

cela fonctionne avec votre constructeur. j'apprécie l'aide! – cmplx96