Ошибка сегментации при попытке распечатать данные связанного списка в обратном порядке с помощью рекурсии - PullRequest
0 голосов
/ 24 апреля 2019

Я создал связанный список узлов.И хотел напечатать данные каждого узла обратно, используя рекурсию технику.Я получил работающий, а также segfault код.Я пытаюсь понять, в чём на самом деле проблема в коде с ошибками.

На самом деле я пытался отладить с помощью 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 ]

4 голосов
/ 24 апреля 2019

Считайте, что вы на последнем узле.

//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 голос
/ 24 апреля 2019

Ваш метод print_list_reversely() вызывается рекурсивно от первого до последнего элемента, и это предполагаемое поведение.

Как вы определили свои списки, следующим последним элементом будет NULL.

если вы раскомментируете две неисправные строки (EDIT: вы раскомментировали их сейчас), когда temp = temp->next; выполняется на последнем элементе, у вас будет ноль. И вы разыменовываете этот указатель с printf("data is %c\n", temp->c);

Следовательно, этот код неверен и является ошибкой.

Вы должны проверить, что ваш указатель не равен нулю, прежде чем вызывать функцию обратно (или разыменовывать ее!)

0 голосов
/ 24 апреля 2019

Последний указатель temp, переданный в рекурсии, равен 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
...