Thread: sorted linked list...why seg faults!

  1. #1
    Registered User
    Join Date
    Mar 2008
    Location
    Toronto
    Posts
    11

    sorted linked list...why seg faults!

    I have a program that adds a name and an age to a structure then that structure is added to a list that's sorted by name and age.

    when i add a struct then go to remove it, seg fault!

    when i add a struct it's all good but when i go to add another struct, seg fault!

    i'm using -g when compiling and valgrind --show-reachable=yes to see the problems with memory.

    i can't figure this out for the life of me, can someone shed some light on as to why i'm getting these seg faults.

    Thanks, ALain

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MAX_LEN 250
    
    typedef struct node 
    {
        char *name;
        int  age;
        struct node *nextName;
        struct node *nextAge;
    }NODE;
    
    int drain_stdin()
    {
        int c;
    
        while((c = getchar()) != '\n' && c != EOF);
    
        return c;
    }
    
    NODE * listInput(NODE *new)
    {
    
        new = malloc(sizeof(NODE));
    	new->name = malloc(sizeof(char)*MAX_LEN + 1);    
        
        if (drain_stdin() != EOF)
        {
            printf("Enter name: ");
            fgets(new->name, MAX_LEN + 1, stdin);
    
            printf("Enter age: ");
            scanf("%d", &new->age);
        }
        else
        {
            printf("An Error Has Occured\n");
        }
        return new;
    }
    
    NODE * insertNameNode(NODE *new, NODE *head1)
    {
        NODE *temp;
        NODE *prev;
    
        new->nextName = NULL;
        
        if (head1 == NULL)
        {
            return new;     
        }
    
        temp = head1;
        prev = NULL; 
        
        while(1) 
        {
    	    if (strcmp(temp->name, new->name) < 0) 
            {
    		    prev = temp; 
    		    temp = temp->nextName;      
    		    continue; 
    	    }
            else/* if(strcmp(temp->name, new->name) >= 0) */
            {
    	        new->nextName = temp;   	
                
    	        if (prev != NULL)
                {
                    prev->nextName = new;  
                }
    	        else
                {
                    head1 = new;  
    	            /*break;*/
                }
            }
        }
        return (head1);    
    }
    
    NODE * insertAgeNode(NODE *new, NODE *head2)
    {
        NODE *temp;
        NODE *prev;
    
        new->nextAge = NULL;
    
        if (head2 == NULL)
        {
            return new;     
        }
    
        temp = head2;
        prev = NULL; 
        
        while(1) 
        {
    
    	    if (temp->age < new->age) 
            {
    		    prev = temp; 
    		    temp = temp->nextAge;      
    		    continue; 
    	    }
            else/* if(temp->age >= new->age) */
            {
    	        new->nextAge = temp;   	
                
    	        if (prev != NULL)
                {
                    prev->nextAge = new;  
                }
    	        else
                {
                    head2 = new;  
    	           /* break;*/ 
                }
            }
        }
        return(head2);
    }
    
    
    NODE * removeNameStruct(NODE *head1, char *nameRemove)
    {
        NODE *prev;
        NODE *root;    
    
        prev = NULL;
        root = head1;    
       
        if (drain_stdin() != EOF )
        {
            printf("Enter Name Of Desired Record To Be Removed: ");
            fgets(nameRemove, MAX_LEN + 1, stdin);
    
            while (root != NULL) 
            { 
                if(strcmp(nameRemove, root->name) == 0)
                {
                    printf("Found The Record\n");
    
                    if (prev != NULL)
                    {
                        prev->nextName = root->nextName;
                    }
                    else
                    {
                        head1 = root->nextName;
                    }
                    root = root->nextName; 
                    /*free(head1);*/
                    break;
                } 
                else 
                {
                    printf("Record NOT Found\n");
         		    prev = root; 
    			    root = root->nextName;
    		    }
            }
        }
        else
        {
            printf("An Error Has Occured\n");
        } 
        return (head1);
    }
    
    NODE * removeAgeStruct(NODE *head2, char *nameRemove)
    {
    
        NODE *prev;
        NODE *root;
    
        prev = NULL;   
        root = head2;    
    
        while (root != NULL) 
        { 
            if(strcmp(nameRemove, root->name) == 0)
            {
                printf("Found The Record\n");
    
                if (prev != NULL)
                {
                    prev->nextAge = root->nextAge;
                }
                else
                {
                    head2 = root->nextAge;
                }
                root = root->nextAge;
                free(head2->name);
                free(head2);
                break;
            } 
            else 
            {
                printf("Record NOT Found\n");
                prev = root;
                root = root->nextAge;
    	    }
        }
        return (head2);
    }
    
    void printName(NODE *head1, NODE *head2)
    {
        if (head1 == NULL) 
        { 
    		printf("List is empty.\n") ; 
    		return; 
    	}
        else
        {    
            while (head1 != NULL) 
            {
                printf("%s %d\n", head1->name, head1->age);
                head1 = head1->nextName;
            }
        }
    }
    
    void printAge(NODE *head1, NODE *head2)
    {
        if (head2 == NULL) 
        { 
    		printf("List is empty.\n") ; 
    		return ; 
    	}
        else
        {    
            while (head2 != NULL) 
            {
                printf("%s %d\n", head2->name, head2->age);
                head2 = head2->nextAge;
            }
        }
    }
    
    
    void freeProg(NODE *head1, NODE *head2)
    {
    /*
        while(head1 != NULL && head2 != NULL)
        {
            free(head2->name);    
            free(head2);
        }    
    */ 
    }
    
    
    int main(void) 
    {
        int choice, count;
        char nameRemove[MAX_LEN + 1];
    
        choice = 0;
        count = 0;
    
        NODE *new;
        NODE *head1;
        NODE *head2;
        
        new = NULL;
        head1 = NULL;
        head2 = NULL;
    
        do
        {
            printf("1. Add structure\n");
            printf("2. Remove structure\n");
            printf("3. Print names\n");    
            printf("4. Print ages\n");
            printf("5. Exit\n");
            scanf("%d", &choice);
    
            if(choice == 1)
            {
                new = listInput(new);
                head1 = insertNameNode(new, head1);
                head2 = insertAgeNode(new, head2);
            }
            else if(choice == 2)
            {
                head1 = removeNameStruct(head1, nameRemove);
                head2 = removeAgeStruct(head2, nameRemove);
            }
    
            else if(choice == 3)
            {
                printName(head1, head2);
            }
            else if(choice == 4)
            {
                printAge(head1, head2);
            }
            else if(choice == 5)
            {
                freeProg(head1, head2);
            }   
            else
            {
                return 0;
            }
            
        }while(choice != 5);    
    
        return 0;
    }
    
    /*
    NODE * removeStruct(NODE *head1, NODE *head2)
    {
        NODE *prev;
        NODE *root;
    
        prev = NULL;
        root = head1;
    
        char nameRemove[MAX_LEN + 1];
       
        if (drain_stdin() != EOF )
        {
            printf("Enter Name Of Desired Record To Be Removed: ");
            fgets(nameRemove, MAX_LEN + 1, stdin);
    
            while (head1 != NULL) 
            { 
                if(strcmp(nameRemove, root->name) == 0)
                {
                    printf("Found The Record\n");
                    if (prev != NULL)
                    {
                        prev->nextName = head1->nextName;
                       
                    }
                    else
                    {
                        root = head1->nextName; 
                        
                    }
                    free(head1);
                    break;
                } 
                else 
                {
         		    prev = head1; 
    			    head1 = head1->nextName;
    		    }
            }
        }
        else
        {
            printf("An Error Has Occured\n");
        } 
        return head1;
    }
    */

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Like I told you in the other thread, you have to break out of your while loop.

    Go back and implement what I said, otherwise, that 30 minutes I took out of my life working on YOUR problem will have been wasted.

    Todd
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Registered User
    Join Date
    Mar 2008
    Location
    Toronto
    Posts
    11
    i have the break; in both the insertName and insertAge function, but still seg fault when adding more than one struct and still seg faults when removing struct. i'm obviously missing something here and i honestly can't see what.

    I appreciate the time you've taken to help me solve my problems. I just can't seem to find the error in my code.

    Thanks, Alain

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Code:
    while(1) 
        {
    	    if (strcmp(temp->name, new->name) < 0) 
            {
    		    prev = temp; 
    		    temp = temp->nextName;      
    		    continue; 
    	    }
    if temp->nextName is NULL (which is always true for the first node in the list) what will happen on the next iteration of the loop?
    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
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    The break I said to remove was removed, but was not added where I said to add. There is no break in the while(1) loop:
    Code:
    NODE * insertAgeNode(NODE *new, NODE *head2)
    {
        NODE *temp;
        NODE *prev;
    
        new->nextAge = NULL;
    
        if (head2 == NULL)
        {
            return new;     
        }
    
        temp = head2;
        prev = NULL; 
        
        while(1) 
        {
    
    	    if (temp->age < new->age) 
            {
    		    prev = temp; 
    		    temp = temp->nextAge;      
    		    continue; 
    	    }
            else/* if(temp->age >= new->age) */
            {
    	        new->nextAge = temp;   	
                
    	        if (prev != NULL)
                {
                    prev->nextAge = new;  
                }
    	        else
                {
                    head2 = new;  
    	           /* break;*/   kudos for removing this one
                }
            }
        }
        return(head2);
    }
    Mainframe assembler programmer by trade. C coder when I can.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. linked list question
    By mikeman in forum C Programming
    Replies: 1
    Last Post: 11-30-2008, 01:56 PM
  2. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  3. Linked List
    By jpipitone in forum C Programming
    Replies: 4
    Last Post: 03-30-2003, 09:27 PM
  4. problem with structures and linked list
    By Gkitty in forum C Programming
    Replies: 6
    Last Post: 12-12-2002, 06:40 PM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM