2017-09-22 3 views
-1

Lors de l'implémentation d'une liste liée en C++, j'ai rencontré un problème avec ma fonction d'insertion d'un nouvel élément à la fin de la liste.Erreur de liste liée - Pourquoi les références tête et queue pointent-elles vers la même adresse?

struct LinkedNode 
{ 
    int data; 
    LinkedNode* next; 
}; 

class LinkedList 
{ 
private: 
    LinkedNode* head; 
    LinkedNode* tail; 
    int size; 
public: 
    LinkedList(); 
    void insert_back(int element); 
    int at(int index); 
    int length(); 
}; 

A l'origine, ma fonction insert_back était la suivante:

void LinkedList::insert_back(int element) 
{ 
    LinkedNode node = {element, 0}; 
    if(size == 0) 
    { 
     head = &node; 
     tail = head; 
    } 
    else 
    { 
     tail->next = &node; 
     tail = tail->next; 
    } 
    ++size; 
} 

Cependant, quand j'itérés une liste d'éléments à quatre, l'impression de chaque élément en tant que tel:

LinkedList myList; 
myList.insert_back(5); 
myList.insert_back(6); 
myList.insert_back(7); 
myList.insert_back(8); 

for(int i = 0; i < myList.length(); ++i) 
{ 
    cout << myList.at(i) << endl; 
} 

la dernier élément de la liste imprimée en premier, puis je recevrais trois valeurs de déchets tels que:

8 
-403642776 
-403642776 
-403642776 

J'ai corrigé cette erreur en modifiant la façon dont je crée un nouveau noeud dans insert_back. Cette fois, j'ai utilisé le nouveau mot-clé.

void LinkedList::insert_back(int element) 
{ 
    LinkedNode* node = new LinkedNode; 
    node->data = element; 
    node->next = 0; 
    if(size == 0) 
    { 
     head = node; 
     tail = head; 
    } 
    else 
    { 
     tail->next = node; 
     tail = tail->next; 
    } 
    ++size; 
} 

Ceci a corrigé l'erreur, mais je ne comprends pas vraiment pourquoi. Pour une raison quelconque, dans mon ancien code, la tête et la queue pointaient toujours à la même adresse, mais elles ne le sont plus lorsque j'utilise de nouvelles. Pourquoi cela pourrait-il être?

+1

Je pense que nous avons besoin d'une réponse canonique "c'est comme ça que vous construisez une liste chaînée en C ou C++". – Bathsheba

+0

@Bathsheba Cette question n'est pas sur la façon de construire une liste liée, il s'agit d'une erreur très spécifique en quelque sorte liée aux pointeurs et l'initialisation d'une structure qui est arrivé à provoquer une erreur dans une liste liée. –

+0

@AnthonyRossello - et, si vous aviez plus d'expérience, vous comprendriez le point soulevé et ne vous plaindriez pas de son manque de pertinence. Vous auriez également utilisé votre débogueur au lieu de ce forum. Les implémenteurs de Linked List se foutent tout le temps et les erreurs sont presque invariablement les mêmes. Tout comme les questions que l'on se pose sur la surcharge d'un cours en C++ par un opérateur - c'est la même série de questions année après année. Je suggère de lire sur le STL et particulièrement sur le concept que les contenants «possèdent» leur contenu. – enhzflep

Répondre

2

Le problème est que le code LinkedNode node = {element, 0}; ... head = &node; de votre première version stocké l'adresse d'une variable locale, qui devient invalide dès que la fonction insert se termine. Cela conduit à un comportement indéfini une fois que vous accédez à ce pointeur plus tard (par exemple, lorsque vous parcourez votre liste).

Dans la deuxième version, avec LinkedNode* node = new LinkedNode;, vous allouez dynamiquement de la mémoire, et un tel objet est valide jusqu'à ce que vous le supprimiez explicitement. Par conséquent, le pointeur reste valide et vous pourrez y accéder plus tard.