2017-11-27 4 views
1

不明なタイトルのため申し訳ありませんが、この問題の記述方法はわかりません。私はコンピュータサイエンスの初年度に入っていますので、C++についてはあまりよく分かりません。しかし、この問題を調べることは役に立たなかった。2回目のリンクリストの構造体にアクセスした後のセグメンテーションフォールト

問題: main関数では、 "printRawData"フレンド関数が2回呼び出されます。この関数は、クラス "LinkedList"によって格納されたリンクリストの各要素を出力することになっています。これは初めて動作しますが、2回目にセグメント違反が発生します。私は本当に何が間違っているのか分かりません。私のT.A.彼は、構造体の文字列変数 "element_name"がアクセスされたときに壊れていると思っています。

申し訳ありませんが、私の問題をうまく説明していない場合や、私があらゆる種類のstackoverflowエチケットを壊している場合は、乱雑なコードです。助けていただければ幸いです。

//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

特にプログラムのどこにでもセグメンテーションフォルトがありますか?セグメンテーション障害が発生するまで何が起こったのかを追跡しましたか? –

+0

My T.A.した。それは何かを出力する前に、printRawDataが呼び出された2回目に発生しました。彼はelement_nameが何らかの形で崩壊していると思っていると言いました。 – Jeremy

+0

"...セグメンテーションフォルトが発生しました...";プログラムをトレースしている場合、出力は無関係でなければなりません。 –

答えて

2

値によってパラメータを渡し、それはLinkedListオブジェクトのコピーを取得void printRawData(LinkedList l)機能。

ただし、コピーにはfirstポインタのコピーが含まれていますが、ノードはコピーされません。このコピーが破棄されると、LinkedListデストラクタはすべてのノードを削除します。

そして元の画像が壊れています。

コピーを作成する代わりに参照を渡すことができます。


これもstd::listノードもコピーされ、「ディープコピー」、(だけではなく、リストの先頭を)実行するコピーコンストラクタと代入演算子を持っている理由です。

+0

ああ!本当にありがとう!それはうまくいった。 – Jeremy

関連する問題