0

なぜ私がセグに障害を起こしているのか理解できません。基本的な考え方は、リンクリストを使用して再帰的に整数を順番に挿入することです。

node* insert(node** head, int integer)
{
    node* temp = malloc(sizeof(node));
    node* temp1;
    node* newNode;

    if(*head == NULL)
    {
        temp->num = integer;
        temp->next = *head;
        *head = temp;
    }
    else if((*head)->num > integer)
    {
        temp = *head;
        temp1 = temp->next; //breaks the link
        temp->next = newNode;   //creates a new node
        newNode->num = integer;  //adds int
        newNode->next = temp1;   //links new node to previously broken node 
        temp1->next = *head; //next node is NULL 
        *head = temp1;  //Makes next node head again
    }

    else
        insert(&((*head)->next), integer);

    return(temp);
}

このコードをGDBで実行したところ、セグメンテーション違反が発生しましtemp1->next = *headたが、その理由がわかりません。私も自分自身を助けるためにメモを入れましたが、それは機能していないと思います。誰かが私がセグメント障害を起こしている理由を教えてもらえますか?ありがとう。

4

4 に答える 4

3
temp1 = temp->next;

前にある必要があります

temp = *head;

(*head)->num > integerとヘッダーに整数を挿入したい場合は、コードが複雑で間違っています。あなたはこのようにそれを行うことができます:

else if((*head)->num > integer)
    {
        temp->next = *head;
        temp->num = integer;
        *head = temp;
    }

そしてその

temp = malloc(sizeof(node));

にのみ呼び出される必要があります

if(*head == NULL)

とに

else if((*head)->num > integer)

したがって、最終的な関数は次のようになります

node* insert(node** head, int integer)
{
    node* temp;

    if(*head == NULL)
    {
        temp = malloc(sizeof(node));
        temp->num = integer;
        temp->next = *head;
        *head = temp;
    }
    else if((*head)->num > integer)
    {
        temp = malloc(sizeof(node));
        temp->next = *head;
        temp->num = integer;
        *head = temp;
    }

    else
        temp = insert(&((*head)->next), integer);

    return(temp);
}

挿入機能を次のようにテストします。

int main (void) {


   node *tmp, *head = NULL;
   insert(&head, 5);
   insert(&head, 7);
   insert(&head, 3);
   insert(&head, 6);
   insert(&head, 4);
   insert(&head, 2);

   for (tmp = head; tmp!=NULL; tmp = tmp->next) {
        printf("tmp->num  %d\n",tmp->num);
   }

}

そしてそれはうまくいきます!

$ ./test
tmp->num  2
tmp->num  3
tmp->num  4
tmp->num  5
tmp->num  6
tmp->num  7
于 2013-03-18T16:25:56.313 に答える
2

したがって、これを初めて経験するときは、頭がヌルであり、そのためのケースがあります。

次回は、headにポインタがあり、次のノードはありません。head->nextはNULLです。

だからあなたが着くとき:

temp1 = temp->next; 

それはそれをNULLに等しく設定しています。そして、あなたがに着くとき

temp1->next = *head; //next node is NULL 

おっと、temp1はnullです。temp1-> nextのようなものはありません。それは、存在しない構造を探しています。

編集:
そして、あなたはあなたが設定したときにあなたがちょうど割り当てたメモリを捨てていますtemp = *head。必要であることが確実になるまで、おそらくメモリを割り当てるべきではありません。insert()つまり、番号がターゲットよりも少なくなるたびに、新しいインスタンスを呼び出します。パスごとに、実際には使用しないメモリを割り当てます。newnodeそして、おそらく、ではなく、にメモリを割り当てたいと思うでしょうtemp

そして、おそらくより良い命名スキームを使用する必要があります。つまり、2回目に挿入を呼び出すと、それはもはや頭ではありません。またはintegerのようなものである可能性があります。のようなものです。小さな問題ですが、それは物事をまっすぐに保つのに役立ちます、そしてそれは入るのに良い習慣です。intToInsertnewValuetemp1savedTail

->next最後に、リストを調べて、新しいアイテムが属する場所を見つけ、新しいノードを作成し、そのフィールドをテールの残りの部分に設定して、戻ったときに何が起こるかを考えてください。... それで?前のノードには、以前のノードをnextまだ指している値があります。そのリンクも更新する必要があります。

于 2013-03-18T16:29:09.443 に答える
1

リンクリストには現在1つのノードしかないと仮定しましょう。

したがって、*head=いくつかのノード。

* head-> next=NULL。

次に、コードを調べてみましょう。

node* insert(node** head, int integer)
{
    node* temp = malloc(sizeof(node));
    node* temp1;
    node* newNode;

    if(*head == NULL)  // condition = false
    {
        temp->num = integer;
        temp->next = *head;
        *head = temp;
    }
    else if((*head)->num > integer)  // let's assume condition = true
    {
        temp = *head;
        temp1 = temp->next; //breaks the link   // temp1 = NULL
        temp->next = newNode;   //creates a new node  // temp1 is not changed
        newNode->num = integer;  //adds int
        newNode->next = temp1;   //links new node to previously broken node 
        temp1->next = *head; //next node is NULL // NULL->next !!!
        *head = temp1;  //Makes next node head again
    }

    else
        insert(&((*head)->next), integer);

    return(temp);
}
于 2013-03-18T16:35:18.237 に答える
0
*head = temp1;

前にある必要があります

temp1->next = *head;
于 2013-03-18T16:27:29.323 に答える