Thread: struct, string, strcmp(), and "segmentation fault"

  1. #1
    Registered User
    Join Date
    Oct 2009
    Posts
    30

    struct, string, strcmp(), and "segmentation fault"

    I'm getting a segmentation fault on the last line noted below. I'm comparing two strings.
    Code:
    struct node {
       char name[25];
       char address[65];
       float amount;
       struct node * next;
    };
    typedef struct node item;
    item * curr, * head, * tail, * new;
    
    
    void insert(char *name_, char *address_, float amount_){
    	
    	new = (item *)malloc(sizeof(item));
    	
    	strcpy (new->name, name_ );
    	strcpy (new->address, address_ );
        	new->amount = amount_;
    
    ........................
    
    	 printf("%s, ", new->name); printf("%s\n, ", head->name);
             //the above print statements where put in as tests. They print two names.   
             //But, the very next line below produces an error: "segmentation fault"
    	if (strcmp(new->name, head->name) < 0){
    ...
    ...
    Last edited by Roger; 11-07-2009 at 10:22 PM.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Make a small working example.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    struct foo
    {
        char name[BUFSIZ];
    };
    int main( void )
    {
        struct foo *a, *b;
        a = malloc( sizeof *a );
        b = malloc( sizeof *b );
        if( a && b )
        {
            strcpy( a->name, "hello" );
            strcpy( b->name, "world" );
    
            if( strcmp( a->name, b->name ) == 0 )
            {
                printf( "\'%s\' is the same as \'%s\'\n", a->name, b->name );
            }
            else
            {
                printf( "\'%s\' is not the same as \'%s\'\n", a->name, b->name );
            }
        }
        free( a );
        free( b );
    
        return 0;
    }

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    Code:
    item * curr, * head, * tail, * new;
    // ...
    	 printf("%s, ", new->name); printf("%s\n, ", head->name);
             //the above print statements where put in as tests. They print two names.   
             //But, the very next line below produces an error: "segmentation fault"
    	if (strcmp(new->name, head->name) < 0){
    Do you assign anything to "head"? From your code snippet, "head" is never set to anything, so youll get a problem when you access "head->name". Does it print "(null)" for the name of "head->name"?

    Also, use "strncpy" instead of "strcpy" as to prevent overflows: strncpy - C++ Reference

  4. #4
    Registered User
    Join Date
    Oct 2009
    Posts
    30
    nadroj, head is NOT null ("John" and "Paul" is printed in my example), but I still get a segmentation fault on the next line.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Show the whole function, not just the parts you feel like showing.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Oct 2009
    Posts
    30
    Quote Originally Posted by quzah View Post
    Show the whole function, not just the parts you feel like showing.

    ....edit
    Last edited by Roger; 11-08-2009 at 06:14 PM.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You aren't assigning new->prev to anything. You need to always be assigning all pointers for a structure. Your first if doesn't assign prev.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Oct 2009
    Posts
    30
    Quzah,
    I don't understand why this works (which I put in just for testing):
    Code:
    printf("%d\n", strcmp(new->name, head->name));
    and this very next line prints a "sementation fault" error:
    Code:
    if (strcmp(new->name, head->name) < 0){..
    .

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It doesn't really matter why one works and another doesn't. You're not setting your pointers up right, so if it "works", it's just you getting lucky.
    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    
    struct node {
       char name[30];
       char address[65];
       float amount;
       struct node * next;
       struct node * prev;
    };
    typedef struct node item;
    item * curr, * head, * tail, * new;
    
    void insert(char *name_, char *address_, float amount_){
        if ( (new = malloc( sizeof *new )) == NULL )
            return;
        strcpy( new->name, name_ );
        strcpy( new->address, address_ );
        new->amount = amount_;
        new->next = new->prev = NULL;
    
        if( head == NULL )
        {
            new-> prev = new->next = new;  /* I assume you want this circular. */
            head = tail = new;
        }
        else
        if( strcmp( new->name, head->name ) < 0 )
        {
            new->prev = head->prev;
            head->prev = new;
            new->next = head;
        }
        else
        if( strcmp( new->name, head->name ) > 0 )
        {
            new->next = head->next;
            new->prev = head;
            head->next = new;
        }
        else
        {
            free( new );
        }
    }
    
    
    int main() {
    	insert("John", "12 main" , 112.2);
    	insert("Paul", "14 oak", 200.5);
    	
    	curr = head;
    	while(curr) {
    		printf("%s, ", curr->name);
    		printf("%s, ", curr->address);
    		printf("%f\n", curr->amount);
    		curr = curr->next;
       }
    
       return 0;
    }

    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Oct 2009
    Posts
    30
    I appreciate your help, but it's not supposed to be circular,,, the reason for the "tail" and "previous" is to run backwards through the list starting at the tail; i.e., the list can be printed forwards from the head or backwards from the tail.

    I'm trying to follow your code, but 1) I'm still a newb, and 2) getting tired and so I got confused with this line too:

    Code:
    if ( (new = malloc( sizeof *new )) == NULL )
            return;

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It allocates the size of the structure, and if malloc fails, returns from the function. If you don't want it to be circular, remove the line that mentions it being circular.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "Segmentation fault"
    By lehe in forum C Programming
    Replies: 5
    Last Post: 04-10-2009, 08:34 AM
  2. Problem with a function ("Segmentation fault")
    By kinghajj in forum C Programming
    Replies: 6
    Last Post: 02-21-2004, 01:31 PM