Reputation: 196
I have created linked list of nodes. And wanted to print the data of each node reversely using recursion technique. I got the working as well as segfaulted code. I am trying to understand whats actually problem in segfaulted code.
Actually I tried debugging using GDB but I dont know exactly how to troubleshoot this. Any clues will be more helpful towards the clear understanding of recursion.
#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;
}
After some GDB debugging got the below info:
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);
Upvotes: 0
Views: 159
Reputation: 12732
Consider you are at the last node.
//temp = temp->next; /* This and next line together*/
//print_list_reversely(temp); /* Causing SEGFAULT */
printf("data is %c\n", temp->c);
You assign tmp
to NULL
and you try to print it causing NULL
pointer dereference.
Consider you have list as below
1->2->NULL
And your recurssion calls are
print_list_reversely(1)
tmp = [2]
---> print_list_reversely(2)
tmp = [NULL]
---> print_list_reversely(NULL)
return;
print(null->c) //Seg fault
Upvotes: 4
Reputation: 1
The last pointer temp passed in the recursion is NULL, so accessing NULL must result in a segment error
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
Upvotes: 0
Reputation: 1236
Your method print_list_reversely()
is called recursively from the first element to the last, and that's the intended behaviour.
Seen how you defined your lists, the next element of the last will be NULL
.
if you uncomment your two faulty lines (EDIT: you uncommented them now), when the temp = temp->next;
is executed on the last element, you have null. And you dereference this pointer with printf("data is %c\n", temp->c);
Therefore, this code is incorrect and segfault.
You have to check that your pointer is not null before calling the function back (or dereferencing it!)
Upvotes: 1