Thread: yet another segmentation fault :)

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    182

    yet another segmentation fault :)

    These segmentation faults are making me feel very humble about my C skills. I have a feeling I don't remember something here.

    Code:
    (gdb) run
    Starting program: /home/eugene/cfiles/a.out 
    
    Program received signal SIGSEGV, Segmentation fault.
    0x08048495 in string2list (sPtr=0xbf8bbdf0, string=0xbf8be000 <Address 0xbf8be000 out of bounds>) at 12.9.c:62
    62			insert( sPtr, *string );
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct listnode {
    	char data;
    	struct listnode *nextPtr;
    };
    
    
    typedef struct listnode ListNode;
    
    
    void insert( ListNode **sPtr, char input );
    void display( ListNode *sPtr );
    void string2list( ListNode **sPtr, char *string );
    
    int main()
    {
    	ListNode *startPtr = NULL;
    	char string[ 10 ] = "a test";
    
    
    	string2list( &startPtr, string );
    //	insert( &startPtr, 'q' );
    //	insert( &startPtr, 'z' );
    //	insert( &startPtr, 'a' );
    	display( startPtr );
    
    
    	return 0;
    }
    
    
    
    
    
    void string2list( ListNode **sPtr, char string[] )
    {
    	
    	while ( string != '\0' ) {
    		insert( sPtr, *string );
    		++string;
    	}
    
    }
    
    
    
    
    void display( ListNode *sPtr )
    {
    	ListNode *currentPtr = NULL;
    	currentPtr = sPtr;
    
    	while ( currentPtr != NULL ) {
    		printf( "%c", currentPtr->data );
    		currentPtr = currentPtr->nextPtr;
    	}
    	printf( "\n" );
    }
    
    
    void insert( ListNode **sPtr, char input )
    {
    	ListNode *newPtr = NULL, *previousPtr = NULL, *currentPtr = NULL;
    
    	newPtr = malloc( sizeof( ListNode ) );
    
    
    	if ( newPtr != NULL ) {
    		newPtr->data = input;
    		newPtr->nextPtr = NULL;
    
    		currentPtr = *sPtr;
    
    		while ( currentPtr != NULL ) {
    			previousPtr = currentPtr;
    			currentPtr = currentPtr->nextPtr;
    		}
    
    		if ( currentPtr == *sPtr ) {
    			newPtr->nextPtr = *sPtr;
    			*sPtr = newPtr;
    		}
    		else {
    			previousPtr->nextPtr = newPtr;
    			newPtr->nextPtr = currentPtr;
    		}
    	}
    
    }

  2. #2
    Registered User
    Join Date
    Apr 2006
    Posts
    58
    You may want to allocate some memory for the node before you start copying things into it.

    Code:
    ListNode *startPtr = NULL;
    Your pointer isn't pointing to anything when you pass it to string2list

    Code:
    string2list( &startPtr, string );

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by samf View Post
    You may want to allocate some memory for the node before you start copying things into it.

    Code:
    ListNode *startPtr = NULL;
    Your pointer isn't pointing to anything when you pass it to string2list

    Code:
    string2list( &startPtr, string );
    allocation of the nodes is made inside the insert function
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    		while ( currentPtr != NULL ) {
    			previousPtr = currentPtr;
    			currentPtr = currentPtr->nextPtr;
    		}
    
    		if ( currentPtr == *sPtr ) {
    			newPtr->nextPtr = *sPtr;
    			*sPtr = newPtr;
    		}
    		else {
    			previousPtr->nextPtr = newPtr;
    			newPtr->nextPtr = currentPtr;
    		}
    Note that when while loop is ended the currentPtr is NULL
    Using this knowledge you can make the red part simplier...
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    58
    Quote Originally Posted by vart View Post
    allocation of the nodes is made inside the insert function
    Yes, that would be true if you actually called that function. But not only did you comment out the calls to that function, but it follows the call to string2list, which is wrong as well.

    Code:
    	string2list( &startPtr, string );
    //	insert( &startPtr, 'q' );
    //	insert( &startPtr, 'z' );
    //	insert( &startPtr, 'a' );
    	display( startPtr );

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    58
    Sorry. My bad. I misread your code.

    Try this:

    Code:
            while ( *string != '\0' ) {
                    insert( sPtr, *string );
                    ++string;
            }
    $ diff x.c.orig x.c
    40c40
    < while ( string != '\0' ) {
    ---
    > while ( *string != '\0' ) {


    $ gcc -Wall -g x.c

    $ a.out
    a test

  7. #7
    Registered User
    Join Date
    May 2006
    Posts
    182
    Man, I'm a little dumb.

    Thanks guys.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    182
    This is my first time using gdb could someone walk me through its output.

    First of all, it says the bug is on the line after the while statement. Why is that?

    Second, why is this an out of bounds error?

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    1. Because the access of the memory you don't own occurs after the coding error that caused it. In many cases the cause of bug is far from the location of the symptom, even in different modules.

    2. Because string is always going to be != '\0', you continue walking the string until you've walked right past the end of it. Eventually, you'll run into memory you don't own and BAM....seg fault (or access violation).

  10. #10
    Registered User
    Join Date
    May 2006
    Posts
    182
    ahh very interesting.

    2. Because string is never dereferenced how can it be out of bound? The value of string be any multiple of sizeof( char ). Shouldn't an out of bounds error occur only if out of bounds memory is actually accessed?

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    string is dereferenced in the insert call.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  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