[英]Seg fault linked list recursion in C
I can't figure out why I'm seg faulting. 我不知道为什么我要断层。 The basic idea is to insert integers in order recursively using a linked list.
基本思想是使用链接列表以递归顺序插入整数。
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);
}
I ran this code in GDB and it seg faults at temp1->next = *head
but I don't understand why. 我在GDB中运行了这段代码,它在
temp1->next = *head
时temp1->next = *head
了段错误,但我不明白为什么。 I even put notes to help myself but I guess it isn't working. 我什至会做笔记以帮助自己,但我想它没有用。 Can someone please tell me why I'm seg faulting?
有人可以告诉我我为什么要断层吗? Thanks.
谢谢。
temp1 = temp->next;
should be before 应该在之前
temp = *head;
In case that the (*head)->num > integer
and If you want to insert the integer in the header than your code is complicated and wrong. 如果
(*head)->num > integer
并且如果您想在标头中插入整数,那么您的代码将是复杂且错误的。 you can do it in this way: 您可以通过以下方式进行操作:
else if((*head)->num > integer)
{
temp->next = *head;
temp->num = integer;
*head = temp;
}
and the 和
temp = malloc(sizeof(node));
should be called only into the 应该只叫入
if(*head == NULL)
and into 并入
else if((*head)->num > integer)
So your final function could be like this 所以您的最终功能可能是这样的
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);
}
I test the insert function with: 我测试插入功能:
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);
}
}
and it works succefully! 它成功地工作了!
$ ./test
tmp->num 2
tmp->num 3
tmp->num 4
tmp->num 5
tmp->num 6
tmp->num 7
So the first time you go through this, head is null and you've got a case for that. 因此,第一次执行此操作时,head为空,并且您有一个理由。
The next time through, head has a pointer, and there is no next node. 在下一次通过时,head有一个指针,并且没有下一个节点。 The head->next is NULL.
head-> next为NULL。
So when you get to: 因此,当您到达:
temp1 = temp->next;
That's setting it equal to NULL. 将其设置为NULL。 And when you get to
当你到达
temp1->next = *head; //next node is NULL
Whoa there, temp1 is null. 那里,temp1为空。 There is no such thing as temp1->next, that's looking for a structure where there is none.
没有temp1-> next这样的东西,它正在寻找不存在的结构。
Edit: 编辑:
And you're throwing away the memory you just allocated when you set temp = *head
. 当您设置
temp = *head
时,您将丢弃刚刚分配的内存。 You probably shouldn't be allocating memory until you're sure you need it. 在确定需要之前,您可能不应该分配内存。 I mean, you call a new instance of
insert()
every time the number is less than the target. 我的意思是,每当数字小于目标数时,您就调用一个
insert()
的新实例。 Each pass you allocate some memory that you don't actually use. 每遍都分配一些您实际上不使用的内存。 And you probably wanted to allocate memory for
newnode
, not temp
. 您可能想为
newnode
分配内存,而不是temp
。
And you should probably use a better naming scheme. 而且您可能应该使用更好的命名方案。 I mean, the second time you call insert, it's no longer the head.
我的意思是,第二次调用插入时,它不再是头。
integer
could be something more like intToInsert
or newValue
. integer
可能更像intToInsert
或newValue
。 temp1
is more like savedTail
. temp1
更像savedTail
。 Minor issue, but it helps keep things straight, and it's a good habit to get into. 次要问题,但这有助于保持直率,这是一个养成的好习惯。
Finally, think about what happens when you've gone through the list, found where the new item belongs, made a new node, set it's ->next
field to the rest of the tail, and returned. 最后,考虑一下当您遍历列表,找到新项目所属的位置,创建新节点,将其
->next
字段设置为其余部分并返回时会发生什么。 ... now what? ... 怎么办? the previous node has a
next
value that's still pointing to what it was before. 前一个节点的
next
值仍指向之前的值。 You need to update that link as well. 您还需要更新该链接。
Lets assume that the linked list currently has only one node. 假设链表当前只有一个节点。
So *head = some node. 所以* head =某个节点。
*head->next = NULL. * head-> next = NULL。
Now lets look into the code: 现在让我们看一下代码:
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);
}
*head = temp1;
应该在之前
temp1->next = *head;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.