C中的段错误链表递归

时间:2013-03-18 16:22:52

标签: c recursion linked-list segmentation-fault

我无法弄清楚为什么我会发生错误。基本思想是使用链表以递归顺序插入整数。

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 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

所以你第一次经历这个,头是空的,你已经有了一个案例。

下一次,head有一个指针,没有下一个节点。 head-> next是NULL。

所以,当你到达:

temp1 = temp->next; 

将其设置为NULL。当你到达

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

哇那里,temp1为空。没有temp1->接下来的东西,那就是寻找没有的结构。

修改
当你设置temp = *head时,你就丢掉了刚分配的内存。在你确定需要它之前,你可能不应该分配内存。我的意思是,每当数字小于目标时,你就会调用insert()的新实例。每次传递都会分配一些实际上没有使用的内存。你可能想为newnode分配内存,而不是temp

你应该使用更好的命名方案。我的意思是,第二次调用insert时,它不再是头部了。 integer可能更像intToInsertnewValuetemp1更像savedTail。小问题,但它有助于保持正确,这是一个很好的习惯。

最后,考虑一下当您浏览列表时发生的情况,找到新项目所在的位置,创建一个新节点,将其->next字段设置为尾部的其余部分,然后返回。 ... 怎么办?上一个节点的next值仍然指向之前的值。您还需要更新该链接。

答案 2 :(得分: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);
}

答案 3 :(得分:0)

*head = temp1;

应该在

之前
temp1->next = *head;