Thread: Segmentation fault with Malloc

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    10

    Segmentation fault with Malloc

    Hi everyone,
    Just a quick background, i'm in my first year of university and have only doune maybe 6-7 weeks of C so try and keep things simple

    I was trying to understand linked lists so was following the tutorial :
    Cprogramming.com Tutorial: Linked Lists
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct node { char c; struct node *next;};
    
    main()
    {
    	struct node *root; // Root node of list
    	struct node *linkptr; // Pointer to link the nodes;
    	
    	root = malloc(sizeof(struct node));
    	root -> next = 0;
    	root -> c = 'L';
    	linkptr = root;
    	
    		while( linkptr != NULL )
    		{
    			printf("%c\n",linkptr->c);
    			//printf("in loop");
    		//	scanf("%c",&(linkptr -> c));
    			linkptr = linkptr -> next;
    		}
    		
    	
    	
    	/* Creates a list a node at the end of the list*/
    	
    	//linkptr -> next = malloc(sizeof(struct node));
    	linkptr->next = malloc(sizeof(struct node));
    
    // Remember linkptr -> next now points to null because we are at the last node in the list so it's ok to allocate a new area of mem  to point to. 
    	
            linkptr = linkptr -> next;
    	
    	if (linkptr == 0)	// checks to see if we are out of memory
    	{
    		printf("out of memory");
    		return(0);
    	}
    	
    	linkptr -> next = 0; // Set the next pointer to NULL to indicate we are at the end of our list.
    	linkptr -> c = 'E';
    	
    	return(0);
    		
    	
    }
    Here is the code i am trying to get to work. I've just run it through GDB and the malloc line is the one giving me a problem. GDB output:
    Program received signal SIGSEGV, Segmentation fault.
    0x00000000004005ab in main () at ll1.c:29

    If i change it to just 'linkptr' instead of 'linkptr -> next' then it works but will that not also overwrite linkptr->char that is stored?

    I might be coming across as very confused so bear with me, the helpdesk guy doesn't know C so i'm pretty stuck at the moment.

    Thanks

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    What is linkptr pointing at immediately after exiting the while loop? Hint: (somewhere bad)
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  3. #3
    Registered User
    Join Date
    Dec 2010
    Posts
    10
    After the while loop linkptr -> next points to null (since it's the end of the list,)
    hence it's fine to malloc and create some more memory as i understand it...

    Could you help me out a little more?

    Cheers.

  4. #4
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Okay, think about it this way:

    The while loop is exited when its condition linkptr != NULL is false. What can you then infer about linkptr?
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > while( linkptr != NULL )
    What is the exit condition of this loop?

    Is it
    a) linkptr == NULL
    b) linkptr = some node in your list


    > linkptr->next = malloc(sizeof(struct node));
    If your answer is a), what does this do?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    10
    It is definitely a, so linkptr is null once the while loop ends?

    But does that not mean that since linkptr is null then linkptr->next it also null so it's ok to create more memory?? Or am i trying to reference a node that just doesn't exsist?

    Thanks for bearing with me.

    edit: And if that's the case how would i go about fixing the problem?

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You want a pointer to the LAST node in the list, when you're done seeking the end.

    lastNodeInList->next (which will be NULL) is set to a new node (from malloc).
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    If linkptr is NULL, which it is, then linkptr->next is going to generate a segfault since it doesn't make any sense. What is NULL->next?

    I don't understand what that while loop is doing there in the first place. It only prints the head of the list.

    Insertion in a linked list is more typically done at the head of the list (if you are not saving some tail pointer) in order to avoid iterating the whole list on each insertion. The steps to do that are simple.

    1) allocate memory for a new node pointed to by some pointer.

    2) set the data field to whatever you want

    3) make the next pointer point to the head of the list.

    4) change the head of the list to point to the new node(new head).

    If you have a tail pointer than you can do something similar at the end in constant (O(1)) time.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault
    By Kemaratu in forum C Programming
    Replies: 6
    Last Post: 11-30-2009, 03:40 AM
  2. malloc + segmentation fault
    By ch4 in forum C Programming
    Replies: 5
    Last Post: 04-07-2009, 03:46 PM
  3. malloc segmentation fault
    By BharathKumar in forum C Programming
    Replies: 5
    Last Post: 06-27-2007, 02:53 AM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM