2017-09-22 1 views
-1

C++でLinked Listを実装する過程で、リストの末尾に新しい要素を挿入するという問題が発生しました。もともとリンクリストエラー - 頭と尾の参照が同じアドレスを指しているのはなぜですか?

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(); 
}; 

次のように、私のinsert_back機能は:

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; 
} 

しかし、私は4要素のリストを反復処理するとき、などの各要素をプリントアウト:

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; 
} 

リストの最後の要素が最初に表示され、次に3つのガベージ値が表示されます。

8 
-403642776 
-403642776 
-403642776 

insert_backで新しいノードを作成する方法を変更することでこのエラーを修正しました。今回は、新しいキーワードを使用しました。

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; 
} 

これでこのエラーは修正されましたが、なぜそれほど効果がないのでしょうか。何らかの理由で、私の古いコードでは、頭と尾は常に同じアドレスを指していましたが、私が新しいものを使用するときはもはやありません。なぜこれができますか?

+1

標準的な「これはCまたはC++でリンクリストを作成する方法です」と答える必要があると思います。 – Bathsheba

+0

@Bathshebaこの質問はリンクされたリストを作成する方法に関するものではなく、リンクされたリストでエラーが発生した構造体のポインタと初期化に関する何らかの非常に特殊なエラーに関するものです。 –

+0

@AnthonyRossello - 経験豊かであれば、その点を理解していて妥当性の欠如について不平を言うことはありません。また、このフォーラムの代わりにデバッガを使用しました。リンクされたリストの実装者はいつもそれを台無しにし、間違いはほとんど変わりません。質問と同様に、C++でクラスの演算子のオーバーロードを見ます - それは毎年同じ質問のセットです。私はSTL、特にコンテナがその内容を所有しているという概念について読んでみることをお勧めします。 – enhzflep

答えて

2

最初のバージョンのLinkedNode node = {element, 0}; ... head = &node;コードにはローカル変数のアドレスが格納されており、insert関数が終了すると無効になるという問題があります。後でこのポインタにアクセスすると、定義されていない動作になります(リストをトラバースするなど)。

2番目のバージョンでは、LinkedNode* node = new LinkedNode;で動的にメモリを割り当てます。このオブジェクトは、明示的に削除するまで有効です。したがって、ポインタは有効なままで、後でそれにアクセスすることができます。

関連する問題