Thread: Segmentation fault in Header file

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    7

    Segmentation fault in Header file

    All,

    I'm hoping you can help me here. I have written a small program for a class to convert decimal to binary and the program itself works, however, I am storing the binary bits in a stack that is in a header file (which I have used successfully before). It appears to push the bits to the stack just fine, however, when I use the printStack function I get a segmentation fault.

    Here is the stack.h header file:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    
    struct stackNode { 
     int data;
    struct stackNode *nextPtr;
    };
    
    
    typedef struct stackNode StackNode;
    typedef StackNode *StackNodePtr;
    
    
    void push( StackNodePtr *topPtr, int info );
    int pop( StackNodePtr *topPtr );
    void printStack( StackNodePtr currentPtr );
    
    
    void push( StackNodePtr *topPtr, int info )
    { 
        StackNodePtr newPtr;
        newPtr = malloc( sizeof( StackNode ) );
        if ( newPtr != NULL ) 
        { 
            newPtr->data = info; 
            newPtr->nextPtr = *topPtr; 
            *topPtr = newPtr; 
        }
        else 
        { /* no space available */
            printf( "%d not inserted. No memory available.\n", info );
        }
    }
    
    
    int pop( StackNodePtr *topPtr )
    { 
        if (*topPtr != NULL)
            {
                StackNodePtr tempPtr;
                int popValue;
                tempPtr = *topPtr; 
                popValue = ( *topPtr )->data; 
                *topPtr = ( *topPtr )->nextPtr;
                free( tempPtr );
                return popValue;
            }
        else
        {
            printf("The list is empty\n");
        }
    }
    
    
    void printStack( StackNodePtr currentPtr )
    { 
    /* if stack is empty */
    if ( currentPtr == NULL ) 
        {
        printf( "The stack is empty.\n\n" );
        }
        else 
        { 
            while ( currentPtr != NULL ) 
            { 
            printf( "%d\n", currentPtr->data );
            currentPtr = currentPtr->nextPtr;
            }
        printf( "\n" );
        }
    }
    And here is the main program that does the conversion:
    Code:
    #include <stdio.h>
    #include "stack.h"
    
    
    int binary (int x);
    
    
    int main()
    {
        int choice = 0;
        printf("\nPlease enter the decimal number for conversion: ");
        scanf("%d", &choice);
        int answer = binary(choice);
    }
    
    
    int binary (int x)
    {
        StackNodePtr Head;
        //base case
        if (x > 0)
        {
            //recursive step
            push(&Head, x%2);
            return binary (x/2);
        }
        else
        {
            printStack(Head);
            return 0;
        }
        
    }
    Anything anyone can point out to help me?

    Marc

    P.S. one other thing of note, whenever I try to modify the printStack function, that function then seems to not work at all.

    Thanks
    Marc

  2. #2
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    The fact you have that code in a header has nothing to do with the problem -

    Please enter the decimal number for conversion: 8
    1
    0
    0
    0
    -2081649835
    So you are attempting to access memory that is not assigned to your data, but i must hand this to others more qualified than me, am sure it is simple, but am not in mood for working it out myself
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  3. #3
    Registered User
    Join Date
    Apr 2013
    Posts
    1,656
    In main(), you to initialize Head to NULL: StackNodePtr Head = NULL; . I didn't check to see if you need any other code adjustments.

  4. #4
    Registered User
    Join Date
    Mar 2013
    Posts
    7
    Rcgldr,

    I did make the change you suggested and it still seems to have the same issues. Here is the output after the change you suggested.

    Please enter the decimal number for conversion: 35
    1
    0
    0
    0
    1
    1
    2665608
    Segmentation fault (core dumped)

    Thanks

  5. #5
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    Code:
    int binary (int x)
    {
        StackNodePtr Head;
    You need to initialize "Head". It currently points to garbage. Thus when you build the linked list you don't have an endnode and when you try to print the contents of your stack you continue to print garbage until you get to an memory address you are not allowed to access.

    And usually header files don't contain definitions, only declarations. The definitions of all your stack functions should be in a separate .c file which you then compile and link to your main program file.

    Bye, Andreas

  6. #6
    Registered User
    Join Date
    Apr 2013
    Posts
    1,656
    I didn't notice that binary() is being used recursively. In this case you need to declare Head to be static (only one instance of Head will be created while your program is running, no matter how many times binary calls itself):

    static StackNodePtr Head = NULL;

  7. #7
    Registered User
    Join Date
    Mar 2013
    Posts
    7
    Rcgldr,

    Sorry, you're right, I should have mentioned that in my first post, however, your suggestion is right on the money! Thanks for the help!

    Marc

  8. #8
    Registered User
    Join Date
    Apr 2013
    Posts
    1,656
    Quote Originally Posted by Marc Oleson View Post
    Rcgldr, Sorry, you're right, I should have mentioned that in my first post, however, your suggestion is right on the money! Thanks for the help!
    It's OK, you posted the code, I just didn't pay attention to it. You should consider getting a source level debugger. If you're running windows, microsoft visual c++ express is free.

  9. #9
    Registered User
    Join Date
    Mar 2013
    Posts
    7
    Rcgldr,

    One more question for you... Now that I have implemented your suggestion, the first binary conversion goes fine, however, if I want to run the function twice without ending the program, I'll have to clear the stack, right? If so, do you know a good way to do that? You can see my attempt below that didn't work...

    Code:
    #include <stdio.h>
    #include "stack.h"
    
    
    int binary (int x);
    
    
    int main()
    {
    	StackNodePtr Head = NULL;
    	int selection = 0;
    	int choice = 0;
    	do
    		// Present user with choices
    		{
    		choice == 0;
    		printf("\n\nPlease choose one of the following options:\n");
    		printf("1. Enter a number for binary conversion:\n");
    		printf("2. Quit program:\n");
    		printf("\nPlease enter your selection: ");
    		scanf("%i", &choice);
    				if (choice == 1)
    				{
    				printf("\nPlease enter the decimal number for conversion: ");
    				scanf("%d", &selection);
    				int answer = binary(selection);
    				//clear the stack
    				/*do
    					{
    						pop(&Head);
    					}
    				while (&Head != NULL); */
    				}
    				else if (choice == 2)
    				{
    				printf("\nThank you for using my program!\n");
    				}
    		}
    	while (choice != 2);
    }
    
    
    int binary (int x)
    {
    	static StackNodePtr Head = NULL;
    	//base case
    	if (x > 0)
    	{
    		//recursive step
    		push(&Head, x%2);
    		return binary (x/2);
    	}
    	else
    	{
    		printf("\nThe binary of your number is: "),
    		printStack(Head);
    		return 0;
    	}
    	
    }
    Thanks,
    Marc

  10. #10
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Your main problem is the static StackNodePtr Head in binary. You have to find a way to reinitialize it to NULL.
    It could by done by an additional boolean parameter say reset that is true only when called from the main program.
    Kurt

  11. #11
    Registered User
    Join Date
    Mar 2013
    Posts
    7
    Zuk,

    I think I understand what you're saying, but I am a newbie to this so I am not sure how this would actually be implemented, can you give me a pointer where to start?

    Marc

  12. #12
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    e.g.
    Code:
    int binary (int x, int reset)
    {
        static StackNodePtr Head = NULL;
        if ( reset ) Head = NULL;
        //base case
        if (x > 0)
        {
            //recursive step
            push(&Head, x%2);
            return binary (x/2, false);
        }
        else   {
            printf("\nThe binary of your number is: "),
            printStack(Head);
            return 0;
        }     
    }
    int main() {
        binary(777, true);
        return 0;
    }

  13. #13
    Registered User
    Join Date
    Apr 2013
    Posts
    1,656
    Change printStack() to take the address of Head as a parameter, and have it use pop() to get values to display, which will free the memory and also set Head back to NULL; You'll need to change the declarations and calls to match this version of printStack():
    Code:
    void printStack( StackNodePtr *currentPtr )
    { 
        while ( *currentPtr != NULL )
        {
            printf( "%d\n", pop(currentPtr));
        }
        printf( "\n" );
    }
    Another "less elegant" option would be to move static StackNodePtr Head = NULL; out of binary() and making it a global. Currently it's essentially a global by being a static, except that its "scope" (its name) only exists in binary(). Then you'd need a program to free the stack (using pop()), which should reset Head = NULL when it completes.
    Last edited by rcgldr; 04-26-2013 at 06:28 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation Fault. When trying to open file.
    By guyle in forum C Programming
    Replies: 5
    Last Post: 02-25-2013, 12:55 PM
  2. Big structure + file pointer = segmentation fault
    By ERJuanca in forum C Programming
    Replies: 6
    Last Post: 03-02-2010, 05:46 PM
  3. Replies: 4
    Last Post: 05-05-2009, 05:35 AM
  4. Segmentation fault with a file pointer?
    By Matt13 in forum C Programming
    Replies: 14
    Last Post: 07-31-2004, 05:53 AM
  5. Segmentation fault with input test file
    By bentles in forum C Programming
    Replies: 20
    Last Post: 04-28-2002, 08:58 PM