2017-07-04 9 views
-2

抽象的な質問:私は、ノードの重リンクリストがあるだろう:Cでリンクリスト未定義の動作

 #node 1  #node 2 
root->[data|next]->[data|next]->NULL 

を、根が宣言されています

*ルートがノードである
struct Node *root = NULL; 

アドレス「NULL」を「保持」するポインタ。

さて、私はリンクリストの最後のノードを削除したいと言って、次のコードは、コンピュータがそのような行動を行うことができますすることができます:

//pop: pop removes last/latter node in linked list and sets new last node to NULL 
void pop(struct Node *root){ 
    struct Node *last; 
    struct Node *current = root; //current point to same node as root 

    while(current->next != NULL){ 
     if(current->next == NULL) {break;} //premature break in traversing of linked list; will stop at last node 
     last = current; //last points to same node as current 
     current = current->next; //move current to next node 
    } 

    last->next = NULL; //point second-to-last node to NULL, making it defacto last node in list 
    free(current); //free last node to heap 

}//end pop 

ポップを呼び出し、関数へのルートを通過した後、プログラムの呼び出しが再びポップ

 #node 1 
root->[data|next]->NULL 

場合は、我々はこのように見えるようにリンクリストを期待するべきである:

root->NULL 
新しいリンクリストは次のようになります

しかし、そうではありません!

List: 1 2 3 
Call pop 
List: 1 2 
Call pop 
List: 1 
Call pop 
List 1980765 

上記はダングリングポインタによって引き起こさ未定義behavoirの例です:私たちは奇妙な振る舞いを観察するまで順に整数要素のリンクリストの場合には、我々はポップを呼び出します。ここで問題となるのは、プログラムがこの動作を回避し、root-> NULLに近い副作用を発生させて、リストが空になるまで、リンクされたリストからすべてのノードをポップする方法です。

+1

pop関数をステップ実行したときに、デバッガからどのようなことが伝えられますか? – Gerhardh

+1

コードにはいくつかの問題があります。ルートがNULLの場合は 'while(current-> next!= NULL){{while}(current-> next!= NULL){last}が初期化されていないのでノードが1つしかない場合は' last-> next = NULL; – Karthick

答えて

1

まず:

この条件は、これまで真であることはありません。

if(current->next == NULL) {break;} 

それが本当だった場合、私たちはそのラインに到達けどwhileループの外に落ちないでしょう。

第二:

あなたは、少なくとも一度は初期化されていない保持lastにポインタをループの本体を実行しない場合。したがって

last->next = NULL; 

はサードNULL

にランダムメモリ位置を設定します:あなたが最後に残った要素を削除しようとすると、あなたがfree(root)に必要

。しかし、rootNULLに設定することはできません。

関連する問題