2016-12-02 1 views
3

Ich versuche eine verkettete Liste in C++ zu codieren, aber ich habe ein Problem. Wenn ich nur ein Element einfüge, funktioniert es, aber wenn ich mehr als eins einfüge, geht es in eine Endlosschleife. Hier ist der Code:Problem mit der verknüpften Liste beim Überschreiben von Variablen

#include "linkedList.hpp" 
#include <iostream> 

linkedList::node::node(int value) 
{ 
    internalValue = value; 
    next = nullptr; 
    previous = nullptr; 
}; 

linkedList::linkedList() 
: header{node(-2)}, trailer{node(-2)} 
{ 
    trailer.previous = &header; 
    header.next = &trailer; 
    size = 0; 
} 

int linkedList::getLength() 
{ 
    return size; 
} 

void linkedList::appendElement(int value) 
{ 

    node newNode = node(value); 
    newNode.next = &trailer; 
    newNode.previous = trailer.previous; 
    (trailer.previous)->next = &newNode; 
    trailer.previous = &newNode; 
    size = size + 1; 
} 

void linkedList::print() 
{ 
    node * current = header.next; 
    while (current -> next != nullptr) 
    { 
     std::cout << current -> internalValue << "->" << "\n"; 
     current = current->next; 
    } 
    std::cout << "v"; 
} 

Nach dem Versuch, es zu debuggen, fand ich, dass das Problem mit dem Bau eines Knotens ist. Also das erste Mal, wenn ich versuche, 5 einzufügen, erstellt das Programm einen Knoten namens neuer Knoten, der dann perfekt angefügt wird.

Was passiert als nächstes, wenn eine zweite Zahl angehängt werden soll, sagen wir 6, das Programm erstellt nicht wirklich ein neues Knotenobjekt. Vielmehr bezieht sich der Variablenname "newNode" immer noch auf den Knoten mit dem darin gespeicherten Wert 5 und ersetzt ihn durch einen Knoten mit dem Wert 6.

Dies schafft verständlicherweise dann eine Endlosschleife, da sie das Array im Wesentlichen kreisförmig macht. Ich weiß nicht, wie ich das beheben soll. Kann mir jemand in die richtige Richtung zeigen?

PS: Sorry, wenn dies sehr einfach ist, ich bin sehr neu in C++ (dies ist erst mein zweiter Tag der Codierung)

+1

'(trailer.previous) -> next = & newNode; trailer.previous = & newNode; 'sieht verdächtig aus.Warum wäre derselbe Knoten sowohl der nächste als auch der vorherige? –

+0

Ich glaube, dass trailer.previous -> Holen Sie sich das "nächste" Datenfeld vom Knoten vor dem Trailer. Ich setze das dann gleich auf den neuen Knoten. Ich denke, es dreht sich grundsätzlich um den Pfeil, der vom Knoten vor dem Trailer auf den neuen Knoten zeigt. Der nächste Teil dreht den Pfeil vom Trailer zum ursprünglichen Knoten, um vom Trailer zum neuen Knoten zu zeigen. –

+0

@ Jean-FrançoisFabre: Es ist normalerweise richtig. In einer doppelt verknüpften Liste muss "& newNode" einmal als ".next" und einmal als ".previous", ** angezeigt werden, es sei denn ** es ist eine Einfügung am Anfang oder am Ende der Liste. – MSalters

Antwort

3

In linkedList::appendElement(int value) Sie einen neuen Knoten auf dem Stapel erstellen (oder 'automatic storage'), was bedeutet, Der Knoten wird zerstört, wenn die Funktion zurückkehrt.

Erstellen Sie stattdessen den Knoten auf dem Heap (oder 'dynamic storage') mit dem Operator new, damit es nicht zerstört wird, wenn die Funktion zurückkehrt.

node* newNode = new node(value); 

Sie müssen auch selbst zu zerstören erinnern Knoten, wenn die Liste zerstört wird oder abgeschnitten, und die meisten C++ Entwickler bald finden es besser, intelligente Zeiger für das verwenden.

+0

der 'neue Knoten' verwirrte meine Vision, ich dachte ein 'neues' wurde gemacht :) Pedantische werden sagen, dass automatische Variablen nicht unbedingt der Stack sind. Es ist abhängig von der Implementierung. –

+0

danke für die antwort. Eine kurze Nachfolgefrage, ich dachte, wir möchten, dass der Knoten zerstört wird. Bleibt seine Präsenz nicht hinter dem Problem zurück, oder denke ich darüber nach? –

+0

@AbidRizvi: Das Problem für Sie ist nicht, ob Sie den Knoten löschen möchten, aber _when_. Da Sie "neue" und dumme Zeiger verwenden, liegt das ganz in Ihrer Verantwortung. – MSalters

Verwandte Themen