Reputation: 801
I am trying to learn how to use structures and linked lists in C but I really don't understand why the following code gives me Segmentation fault:
I have 3 files named list.h, operations.c and main.c. In the file list.h:
#include <stdio.h>
#include <stdlib.h>
typedef char DATA;
struct linked_list {
DATA d;
struct linked_list *next;
};
typedef struct linked_list ELEMENT;
typedef ELEMENT *LINK;
LINK string_to_list(char s[]);
void print_list(LINK);
The file operations.c:
#include "list.h"
LINK string_to_list(char s[]){
LINK head = NULL;
if (s[0]) {
ELEMENT c = {s[0], NULL};
c.next = string_to_list(s+1);
head = &c;
}
return head;
}
void print_list(LINK head) {
if(head != NULL){
putchar(head -> d);
print_list(head -> next);
} else {
putchar('\n');
}
}
The file main.c:
#include "list.h"
int main(void) {
LINK head = string_to_list("wtf");
print_list(head);
return 0;
}
Upvotes: 1
Views: 108
Reputation: 158469
In string_to_list
you are taking the address of a local variable(which on most modern implementations is stored on the stack) in your if statement:
head = &c;
and then returning that address here:
return head;
the variable c
will no longer exist after the end of the if statement, this is undefined behavior. The C99 draft standard section 6.2.4
Storage durations of objects paragraph 2 says:
[...]If an object is referred to outside of its lifetime, the behavior is undefined.[...]
Upvotes: 2
Reputation: 12515
if (s[0]) {
---> ELEMENT c = {s[0], NULL};
c.next = string_to_list(s+1);
head = &c;
}
return head;
Is a local memory. As soon as you leave the function (or even the code block), that memory is freed and is no longer valid. You need to malloc()
it, or pass in some memory for this function to use for it to live beyond this function.
Upvotes: 2
Reputation: 180917
if (s[0]) {
ELEMENT c = {s[0], NULL}; // Allocate space for struct on the stack
c.next = string_to_list(s+1);
head = &c; // Save the address to head
} // <-- poof, c goes out of scope and is deallocated from the stack
return head; // <-- return address of deallocated object
Upvotes: 4