0

Cで連結リストを作成する方法を学んでいます。私のプログラムはコンパイルされますが、何らかの理由で理解できず、セグメンテーション違反が発生しています。私はしばらく問題を理解しようとしてきましたが、運がありません。欠陥のあるコードは次のとおりです。

int len()
{
    struct list * current = head;
    int length = 0; 

    while (current != NULL)
    {
        length++;
        current = current -> next; //move to next node
    }
    return length; 
}


struct list * search ( int key)
{
    struct list * current = head;

    while (current != NULL && current->data != key)
        current = current -> next;

    if (current != NULL && current -> data == key)
        return current;
    return NULL;
}



/* Insert a new data element with key d into the end of the list. */
void insert(int d )  //  at the end
{
    struct list * current = head; 
    struct list * new;
    while (current -> next != NULL)
        current = current -> next;
    new = (struct list *)malloc(sizeof(struct list));
    new -> data = d; 
    current -> next = new;
    new -> next = NULL;     
}


void insertAfter(int d, int where )  //  insert at the middle
{
    struct list * marker = head;
    struct list * new;

    while(marker -> data != where)
        marker = marker -> next;
    new = (struct list*)malloc(sizeof(struct list));

    new -> next = marker -> next; 
    marker -> next = new;
    new -> data = d; 
}


/* Remove the node with value d from the list */
/* assume no duplicated keys in the list */
/* If the list is empty, call prtError() to display an error message and return -1. */

void delete(int d)
{
    struct list * current1 = head; 
    struct list * current2;

    if (len() == 0)
    { //prtError("empty");
        exit(0);
    }
    if (head -> data == d)
    { 
        head = head -> next;
    }

    //Check if last node contains element
    while (current1->next->next != NULL)
        current1 = current1->next;

    if(current1->next->data == d)
            current1->next == NULL; 


    current1 = head; //move current1 back to front */

    while(current1 -> next -> data != d)
        current1 = current1 -> next; 

    current2 = current1 -> next;
    current1 -> next = current2 -> next; 

}

次の行の削除メソッドでセグメンテーション違反が発生しています。

while(current1 -> next -> data != d)

なぜこれが間違っているのですか?

4

5 に答える 5

0

あなたが投稿したコードには多くの問題がありますが、コメントであなたが懸念していることについて言及していますinsert()。クラッシュする理由は、呼び出されたheadときに NULL である場合、NULL ポインターを逆参照するためinsert()です。

headNULL のときに挿入するには、特別なケースが必要です。

if (head) {
    while (current -> next != NULL)
        current = current -> next;
}
new = (struct list *)malloc(sizeof(struct list));
new -> data = d;
if (current) {
    current -> next = new;
} else {
    head = new;
}
new -> next = NULL;

他の関数で同様の問題がないか確認する必要があります。search()ループ内で NULL ポインターの逆参照を回避する例として、関数を使用してください。

于 2013-07-09T21:41:07.463 に答える
0

にいくつかの問題がありますinsert:

while (current -> next != NULL)

currentかどうかを確認していませんNULL。にも同様の問題がありますdelete

if (head -> data == d)

headここで確認する必要があります。

while (current1->next->next != NULL)

も問題です。

于 2013-07-09T21:42:00.463 に答える
0

多分それはあるinsertAfter

while(marker -> data != where)
    marker = marker -> next;

を持つノードdata == whereが見つからない場合はmarkerNULLポインターになります。
ポインターは、コードのNULL後半で逆参照されます。

new = marker -> next;

セグメンテーション違反になります。marker->next != NULLそれを避けるべきかどうかを確認する:

while(marker->next != NULL && marker -> data != where)
    marker = marker -> next;

ただし、デバッグ シンボル (-gオプション) を使用してプログラムをコンパイルし、GDB などのデバッガーで 1 行ずつ実行するようにしてください。

于 2013-07-09T21:58:20.093 に答える