Home > Software design >  Why do I get a segmentation fault when trying to create a linked list using structures?
Why do I get a segmentation fault when trying to create a linked list using structures?

Time:09-16

[Solved] Check the edit at the end of the post for the correct solution!

I am writing a code to create a linked list using structures in C language.

I have defined the structure with a data type and a pointer to structure type. Further I have used typedef to typecast this to Node_s.

I am using a function to initialise the first node; which basically won't contain any value but just returns the headpointer, which I will use to point to my next structure (node).

In the main block, I am initialising a structure pointer with Null value and then feeding the value from initialiser function to this pointer.

But this code is returning zsh: segmentation fault . Can someone explain me the issue!

#include <stdio.h>
#include <stdlib.h>
//Node* Initialize;  

typedef struct Node {
    int data;
    struct Node* next;
} Node_s;


Node_s* Initialize(){

    Node_s init_node;

    Node_s* headlist;
    init_node.data = 0;
    init_node.next = headlist;

    return headlist;

}

int main() 

{

    Node_s* ptr = NULL;
    ptr = Initialize(); 

    // 1st Node
    ptr->data = 1;
    Node_s* ptr2 = NULL;
    ptr->next = ptr2;

    // 2nd Node
    ptr2->data = 1;
    ptr2->next = NULL;

    printf(" \n done deal %d", (*ptr2).data );

    return 0;
}

I successfully made the following changes and got the code working for me; thanks for all the help and the negative unsupportive comments as well!

  1. Assign the pointer of init_node in headlist rather than doing the other way round; which makes no sense! So use headlist = init_node.next ;

2.Before using ptr->data = 1; ; the structure pointer ptr must point to a valid structure. Although we have gotten the pointer information from Initialise, we still need to point it to a valid node (structure)

  1. Thus declare a structure named two and then assign your pointer to this structure! Node_s two; and then Node_s* ptr = Initialize(); . This will be logical and correct!

     #include <stdio.h>
     #include <stdlib.h>  
    
     typedef struct Node {
         int data;
         struct Node* next;
     } Node_s;
    
    
     Node_s* Initialize(){
    
     Node_s init_node;
    
     Node_s* headlist;
     init_node.data = 0;
     headlist = init_node.next ;
     return headlist;
    
     }
    
     int main() 
    
     {
    
     Node_s two;
     Node_s* ptr = Initialize(); 
     ptr = &two;
    
     // 1st Node
     two.data = 1;
     Node_s three;
     two.next = &three;
    
     three.data = 2;
     three.next = NULL ;
    
    
     printf(" \n done deal %d", (three).data );
    
     return 0;
     }
    

CodePudding user response:

  1. main(): the variable ptr is uninitialized as returned from Initialize(). If it points to NULL or any other memory you don't have access to it will segfault when you deference it's members (ptr->data).

  2. main(): the variable ptr2 is initialized to NULL, then you try to dereference it set its members. This will trigger a segfault if you get there.

  3. Initialize(): init_node is a local variable and has no effect outside the function.

  4. Initialize(): headlist is uninitialized as I mentioned above.

  5. Initialize(): I suggest you change the signature to Node_s *Initialize(int data) so you can set the data to the value you need instead of a dummy value.

Here's a better starting point:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node_s;

Node_s *Initialize(int data) {
    Node_s *headlist = malloc(sizeof(*headlist));
    if(!headlist) {
        printf("malloc failed\n");
        return NULL;
    }
    headlist->data = data;
    headlist->next = NULL;
    printf("done deal %d\n", headlist->data);
    return headlist;
}

int main() {
    Node_s *ptr = Initialize(1);
    if(!ptr)
         return 1;

    ptr->next = Initialize(2);
    if(!ptr->next)
        return 1

    return 0;
}

The next step would be to eliminate the printf("done deal ...) statement in favor of a function that prints your linked list. Then write a function that frees the linked list. Then write a function that can Append(int data) an element to your list to replace Initialize().

  • Related