我已经创建了节点的链接列表。并希望使用递归技术反向打印每个节点的数据。我得到了有效的代码以及段错误代码。我试图了解段错误代码中实际存在的问题。
实际上,我尝试使用GDB进行调试,但是我不知道如何解决此问题。任何线索都将有助于对递归的清晰理解。
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
char c;
struct node *next;
} node_t;
node_t *head = NULL;
void insert_list(node_t *node)
{
static node_t *temp = NULL;
if (!head) {
head = node;
//temp = node;
}
else {
temp->next = node;
}
temp = node;
}
void create_list(char c)
{
node_t *temp = NULL;
temp = malloc(sizeof(node_t));
if (temp) {
temp->c = c;
temp->next = NULL;
insert_list(temp);
}
else
return;
}
void print_list_reversely(node_t *temp)
{
if (!temp)
return;
//print_list_reversely(temp->next); /* Working piece */
temp = temp->next; /* This and next line together*/
print_list_reversely(temp); /* Causing SEGFAULT */
printf("data is %c\n", temp->c);
return;
}
int main()
{
create_list('a');
create_list('b');
create_list('c');
print_list_reversely(head);
return 0;
}
经过GDB调试后,获得了以下信息:
A)print_list_reversely(temp-> next);
Breakpoint 4, print_list_reversely (temp=0x0) at create.c:40
40 if (!temp)
(gdb) p temp
$5 = (node_t *) 0x0
(gdb) n
41 return;
(gdb) n
47 }
(gdb) n
print_list_reversely (temp=0x602050) at create.c:45
45 printf("data is %c\n", temp->c);
=======
B)temp = temp-> next; print_list_reversely(temp);
Breakpoint 4, print_list_reversely (temp=0x0) at create.c:40
40 if (!temp)
(gdb) p temp
$3 = (node_t *) 0x0
(gdb) n
41 return;
(gdb) n
47 }
(gdb)
print_list_reversely (temp=0x0) at create.c:45
45 printf("data is %c\n", temp->c);
答案 0 :(得分:4)
考虑您位于最后一个节点。
//temp = temp->next; /* This and next line together*/
//print_list_reversely(temp); /* Causing SEGFAULT */
printf("data is %c\n", temp->c);
您将tmp
分配给NULL
,并尝试打印它,导致NULL
指针取消引用。
请考虑以下列表
1->2->NULL
您的递归调用是
print_list_reversely(1)
tmp = [2]
---> print_list_reversely(2)
tmp = [NULL]
---> print_list_reversely(NULL)
return;
print(null->c) //Seg fault
答案 1 :(得分:1)
您的方法print_list_reversely()
从第一个元素到最后一个元素被递归调用,这就是预期的行为。
看到您如何定义列表,最后一个的下一个元素将是NULL
。
如果取消注释两条错误的行(编辑:您现在取消注释),则在最后一个元素上执行temp = temp->next;
时,您将具有null。然后用printf("data is %c\n", temp->c);
因此,此代码不正确且存在段错误。
您必须检查指针是否为null,然后再调用该函数(或取消引用它!)
答案 2 :(得分:0)
递归中传递的最后一个指针温度为NULL,因此访问NULL必须导致段错误
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005c1 in print_list_reversely (temp=0x0) at linked_list.c:40
40 printf("data is %c\n", temp->c);
(gdb) bt
#0 0x00000000004005c1 in print_list_reversely (temp=0x0) at linked_list.c:40
#1 0x00000000004005bd in print_list_reversely (temp=0x601050) at linked_list.c:39
#2 0x00000000004005bd in print_list_reversely (temp=0x601030) at linked_list.c:39