2017-11-27 2 views
1

Entschuldigung für den unklaren Titel, ich weiß wirklich nicht, wie ich dieses Problem beschreiben soll. Ich bin in meinem ersten Jahr der Informatik, also weiß ich wirklich nicht viel über C++. Das Nachschlagen dieses Problems hat jedoch nicht geholfen. Das Problem: In der Hauptfunktion wird die Friend-Funktion "printRawData" zweimal aufgerufen. Die Funktion soll jedes Element der verknüpften Liste drucken, das von der Klasse "LinkedList" gespeichert wird. Es funktioniert das erste Mal, aber beim zweiten Mal bekomme ich einen Segmentierungsfehler. Ich habe wirklich keine Ahnung, was ich falsch mache. Mein T.A. sagte er denkt, dass die Stringvariable "element_name" der Struktur beim Zugriff beschädigt wird.Segmentierungsfehler erst nach dem zweiten Zugriff auf die Struktur in der verketteten Liste

Entschuldigung für den unordentlichen Code, wenn ich mein Problem nicht gut erkläre, oder wenn ich irgendeine Art von Stackoverflow-Etikette breche. Ich schätze jede Hilfe, die ich bekomme.

//Note: C++ 11 is needed, due to to_string use 
#include <iostream> 
#include <string> 

using namespace std; 

struct Node { 
    string element_name; 
    int element_count; 
    Node* next; 
}; 

class LinkedList{ 
    private: 
    Node* first; 
    public: 
    LinkedList(); 
    ~LinkedList(); 
    bool isEmpty(); 
    void AddData(string name, int count); 
    friend void printRawData(LinkedList l); 
}; 

//where the error occurs 
void printRawData(LinkedList l){ 
    Node* n = l.first; 
    while (n != NULL) { //iterates through the linked list and prints each element 
    cout << n->element_name << " : " << n->element_count << endl; 
    n = n->next; 
    } 
} 

LinkedList::LinkedList(){ 
    first = NULL; 
} 

LinkedList::~LinkedList(){ 
    Node* n = first; 
    while (n != NULL) { 
    Node* temp = n; 
    n = temp->next; 
    delete temp; 
    } 
} 

bool LinkedList::isEmpty(){ 
    return first == NULL; 
} 

void LinkedList::AddData(string name, int count){ 
    Node* newnode = new Node; 
    newnode->element_name = name; 
    newnode->element_count = count; 
    newnode->next = NULL; 

    Node* n = first; 

    //if the linked list is empty 
    if(n == NULL){ 
    first = newnode; 
    return; 
    } 

    //if there's only one element in the linked list, 
    //if the name of first element comes before the name of new element, 
    //first element's pointer is to the new element. 
    //otherwise, the new node becomes the first and points to the previous first 
    //element. 
    if (n->next == NULL){ 
    if (n->element_name < newnode->element_name){ 
     n->next = newnode; 
     return; 
    } else { 
     newnode->next = first; 
     first = newnode; 
     return; 
    } 
    } 

    //if the first element's name comes after the new element's name, 
    //have the new element replace the first and point to it. 
    if (n->element_name > newnode->element_name){ 
    newnode->next = first; 
    first = newnode; 
    return; 
    } 

    //iterating through linked list until the next element's name comes after 
    //the one we're inserting, then inserting before it. 
    while (n->next != NULL) { 
    if (n->next->element_name > newnode->element_name){ 
     newnode->next = n->next; 
     n->next = newnode; 
     return; 
    } 
    n = n->next; 
    } 

    //since no element name in the linked list comes after the new element, 
    //the node is put at the back of the linked list 
    n->next = newnode; 
} 



main(){ 
    LinkedList stack; 

    stack.AddData("Fish", 12); 
    stack.AddData("Dog", 18); 
    stack.AddData("Cat", 6); 

    printRawData(stack); 
    printRawData(stack); 
} 
+1

Erhalten Sie einen Segmentierungsfehler irgendwo im Programm? Haben Sie verfolgt, was bis zu dem auftretenden Segmentierungsfehler passiert? –

+0

Mein T.A. hat getan. Es passierte beim zweiten Aufruf von printRawData, bevor etwas ausgegeben werden konnte. Er erwähnte, dass er dachte, element_name würde irgendwie beschädigt werden. – Jeremy

+0

"... was passiert, bis der Segmentierungsfehler auftritt ..."; und wenn Sie das Programm verfolgen, sollte die Ausgabe irrelevant sein. –

Antwort

2

Die Funktion void printRawData(LinkedList l) gibt den Parameter durch einen Wert, so wird es ein kopieren des LinkedList Objekts. Die Kopie enthält eine Kopie des first-Zeigers, kopiert jedoch keine der Knoten. Wenn diese Kopie also zerstört wird, löscht der Destruktor LinkedList alle Knoten.

Und dann ist das Original beschädigt.

Möglicherweise möchten Sie eine Referenz übergeben, anstatt eine Kopie zu erstellen. Diese


ist auch der Grund, warum die std::list Kopierkonstruktoren hat und Zuweisungsoperatoren, die eine „tiefe Kopie“ durchführen, wo die Knoten auch kopiert (und nicht nur die Listenkopf).

+0

Oh! Vielen Dank! das hat funktioniert. – Jeremy

Verwandte Themen