2017-03-02 9 views
-5

このwhileループではセグメンテーションフォルトが発生していることがわかりますが、理由はわかりません。セグメンテーションフォールトを示すクラスC++でのリンクリストの実装

#include<iostream> 

using namespace std; 

class zDepthList { 

     typedef struct node { 
       int data; 
       node* next; 
       node* prev; 
     } Node; 

public: 

     zDepthList() { 
       head = NULL; 
     } 

     zDepthList(int array[], int length) { 

       Node *temp, *ptr; 
       int i = 0; 

       while(i != length - 1) { 
         temp = head; 
         ptr = new Node; 
         ptr->data = array[i]; 
         i++; 
         ptr->next = NULL; 

         if(head == NULL) { 
           head = ptr; 
           ptr->prev = NULL; 
         } 

         else { 
           while(temp != NULL) { 
             temp = temp->next; 
           } 
         } 
         temp->next = ptr; 
         ptr->prev = temp; 
       } 
     } 

     void out(const char order) { 

       cout << head->data << endl; 

     return; 
     } 

private: 
     Node *head; 
}; 
+0

メインプログラムでこのクラスをどのように使用しているかを確認する必要があります。 – vincent

+0

私たちはあなたの(家)仕事をするつもりはありません。 –

+0

私のメインは、30要素の配列と配列の長さを渡します(zDepthList z(1、30);)。関数(z.out( 'f'))を呼び出します。 – aashman

答えて

1

headNULLに初期化する必要があります。

そしてループを中断するための条件であるため、このwhileループ

    else { 
          while(temp != NULL) { 
            temp = temp->next; 
          } 
        } 
        temp->next = ptr; 
        ptr->prev = temp; 

後ポインタtempNULLに等しいです。したがって、このステートメント

    temp->next = ptr; 

結果が未定義の結果になります。

ダブルリンクリストを使用している場合は、データノードtailを導入するのは自然です。新しいノードを追加するのは簡単です。

ですから、コンストラクタはここで次のよう

zDepthList() : head(nullptr), tail(nullptr) 
    { 
    } 

    zDepthList(const int a[], size_t n) : head(nullptr), tail(nullptr) 
    { 
     for (size_t i = 0; i < n; i++) 
     { 
      Node *tmp = new Node { a[i], nullptr, tail }; 
      tail == nullptr ? head = tmp : tail->next = tmp; 
      tail = tmp; 
     } 
    } 

を見ることができます。この場合、

class zDepthList { 
//... 
private: 
     Node *head, *tail; 
}; 

を含めるべきであることは実証プログラムは、プログラムの出力が

ある

#include <iostream> 

class zDepthList { 

    typedef struct node { 
     int data; 
     node* next; 
     node* prev; 
    } Node; 

public: 

    zDepthList() : head(nullptr), tail(nullptr) 
    { 
    } 

    zDepthList(const int a[], size_t n) : head(nullptr), tail(nullptr) 
    { 
     for (size_t i = 0; i < n; i++) 
     { 
      Node *tmp = new Node{ a[i], nullptr, tail }; 
      tail == nullptr ? head = tmp : tail->next = tmp; 
      tail = tmp; 
     } 
    } 


    std::ostream & out(std::ostream &os = std::cout) const 
    { 
     for (Node *current = head; current; current = current->next) 
     { 
      os << current->data << ' '; 
     } 

     return os; 
    } 

private: 
    Node *head, *tail; 
}; 

int main() 
{ 
    int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

    zDepthList l(a, sizeof(a)/sizeof(*a)); 

    l.out() << std::endl; 
} 

です

0 1 2 3 4 5 6 7 8 9 
+0

ありがとうございました。私は嫌な焙煎tho笑を得た – aashman

+0

@aashman全く。どういたしまして。 –

1

あなたは決してheadと設定しますが、あなたはそれにアクセスします。これは初期化されていないことを意味し、これはUBです。

あなたは2つのctorsを持っていて、パラメータなしで呼び出されたときはheadを初期化します。

+0

'head'がコンストラクタに設定されています – user4581301

+0

2番目のコンストラクタの先頭でheadをNULLに設定しましたが、segフォルトがまだ存在します。 – aashman

+0

'head'が' NULL'の場合、 'temp = head'を実行し、' temp-> next = ptr'を 'NULL'' temp'で実行します。 null参照を参照解除すると、未定義の動作になります。 –

関連する問題