尝试使用递归反向打印链接列表数据时出现分段错误

时间:2019-04-24 07:29:07

标签: c recursion linked-list segmentation-fault

我已经创建了节点的链接列表。并希望使用递归技术反向打印每个节点的数据。我得到了有效的代码以及段错误代码。我试图了解段错误代码中实际存在的问题。

实际上,我尝试使用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);

3 个答案:

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