Search code examples
cstructlinked-listsegmentation-faultnodes

Segmentation Fault In Linked List Append


I have been using linked list and I have used the following code for append function which i wrote in a new file and it works perfectly but when I copy it my main code it gives segmentation fault at while(current->next != null) . It does not give any warning while compiling so I don't know whats the issue here.

// Linked List Node for Reading Comments
struct Node{
    char value;
    struct Node *next;
};

void append(struct Node * headNode, char newElement){
    struct Node *newNode = malloc(sizeof(struct Node));  //Dynamically Allocating Memory for New Node                   
    struct Node *current = headNode;                     //Creating A Node to traverse the linked list

    newNode->value = newElement;                         //Assigning the values of newNode to the given value
    newNode->next = NULL;                                //Setting next value to be null since its the last node

    if (headNode == NULL){                               //Checking if headnode is empty
        headNode = newNode;                              //Assigning headnode and tailnode to be newnode
    }

    else {                
        while(current->next != NULL){                    //Traversing through the linked list
            current = current->next;
        }
        current->next = newNode;                         //Setting tailnode's next to be newnode   

    }
 
}

void printLinkedList(struct Node* headNode){
    while(headNode != NULL){
        fprintf(stderr,"%c",headNode->value);
        headNode = headNode->next;
    }
}

If anyone can comment on this please do.


Solution

  • Your code does not allow to add a node to an empty list. If you try and did not initialise your head pointer on the calling side, you may get such behavior.

    For instance, in main you could have:

        struct Node* head; // not initialised
        append(head, 'a'); 
        printLinkedList(head);
    

    These are then the issues:

    • If head happens to be not NULL, then the else block will kick in and the current pointer will reference some unintended memory address.
    • append will not change the head variable of main. It will only modify a local variable that happens to have a similar name (headNode).

    To correct, pass the address of head to the append function, and let append deal with this accordingly:

    void append(struct Node ** headNode, char newElement) {
        struct Node *newNode = malloc(sizeof(struct Node));
        struct Node *current = *headNode;
        newNode->value = newElement;
        newNode->next = NULL;
    
        if (*headNode == NULL) {
            *headNode = newNode;
        } else {                
            while(current->next != NULL) {
                current = current->next;
            }
            current->next = newNode;
        }
    }
    

    Note the additional * wherever headNode occurs. In main:

        struct Node* head;
        append(&head, 'a');
        printLinkedList(head);