Reputation: 25
I'm writing a small program that prints a linked list. This list contains a string and a pointer to the next node.
I pass the linked list to a function that adds a new node and fills data field.
When I get back to main function and try to print the list content I get segmentation fault error, although from the function add_node I can print the content of the node.
I want to be able to pass a list and a string to a function and the function must add a new node to the list with the string I passed.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
char filename[25];
struct node *next;
};
typedef struct node LISTNODE;
typedef LISTNODE *LISTNODEPTR;
void add_node(LISTNODEPTR *nFile, char *chaData);
int main (int argc, char *argv[])
{
LISTNODEPTR nFile = NULL;
printf("Printing list\n");
add_node(&nFile, "file.txt");
printf("%s\n", nFile->filename);
free(nFile);
return 0;
}
void add_node(LISTNODEPTR *nFile, char *chaData)
{
LISTNODEPTR head = *nFile;
LISTNODEPTR newNode;
newNode = (LISTNODEPTR) malloc(sizeof (struct node));
strcpy(newNode->filename, chaData);
printf("%s\n", newNode->filename);
newNode->next = head; //link next. newNode next points to head (beginning of the list). At this time (head & newNode)->2nd->3rd->NULL
head = newNode;
}
Output: Printing list file.txt Segmentation fault
OS: Linux sisdvb02 2.6.35-28-server #49-Ubuntu SMP Tue Mar 1 14:55:37 UTC 2011 x86_64 GNU/Linux
Compiler: gcc -Wall -o list list.c
Upvotes: 2
Views: 1608
Reputation: 25705
nFile
in your add_node()
function does not change. It still points to NULL
and since you try to dereference a NULL
you get a segmentation violation error. Btw, use Valgrind to help you with such problems.
Change your function to something like this:
void add_node(LISTNODEPTR *nFile, char *chaData)
{
LISTNODEPTR head = nFile;
LISTNODEPTR newNode;
newNode = (LISTNODEPTR) malloc(sizeof (struct node));
strcpy(newNode->filename, chaData);
printf("%s\n", newNode->filename);
newNode->next = head; //link next. newNode next points to head (beginning of the list). At this time (head & newNode)->2nd->3rd->NULL
head = newNode;
nFile = head;
}
Upvotes: 3
Reputation: 2216
The most important thing IMHO is to learn how to debug failures like this. It's handy to use gdb
to learn where the program crashed and what the program state was.
$ gcc -Wall -g test.c -o test
$ gdb ./test
...
(gdb) run
...
Program received signal SIGSEGV, Segmentation fault.
...
(gdb) bt
#0 __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:32
#1 0x00007ffff7aa783c in _IO_puts (str=0x0) at ioputs.c:37
#2 0x0000000000400612 in main (argc=1, argv=0x7fffffffe6a8) at test.c:24
(gdb) frame 2
#2 0x0000000000400612 in main (argc=1, argv=0x7fffffffe6a8) at test.c:24
24 printf("%s\n", nFile->filename);
(gdb) print nFile
$1 = (LISTNODEPTR) 0x0
bt
gives me the backtrace, showing me exactly where the program was when it crashed. And I know from print nFile
that nFile
was still NULL. Why? Well, you can see that you are setting head = newNode
as the last line of add_node
(assigning to a temporary variable which is about to be thrown away), where I assume you intended to set *nfile = newNode
(assigning to the caller's variable by way of the pointer) instead.
Upvotes: 0
Reputation: 1328
Inside add_node()
, you modify head
variable, which is only local variable. This does not affect nFile
variable in main()
- it's still NULL
when control returns to main()
, which is why you get segmentation fault.
The last line in add_node()
should be:
*nFile = newNode;
Upvotes: 0
Reputation: 70523
You have a pointer to null. You then assign this to another variable, so that variable now points to null. Then you allocate memory and point at that memory. This does not change that the original pointer is still pointing to null.
Change the last line in the function to
*nFile = head;
also if you don't want to have a buffer overflow bug change to this:
strncpy(newNode->filename, chaData, 25);
newNod->filename[24] = 0;
Upvotes: 0