Question

Recently I have been using C a lot (I normally use higher level languages) and have been running into a problem when managing lists.

Specifically, adding nodes to a linked list. I often end up writing something similar to the sample code below. As far as I can see, it should all work fine however no new nodes are appended to the list.

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

typedef struct ListNode {
    struct ListNode* next;
    int data;
} ListNode;

ListNode* createListNode(int data){
    ListNode* node = (ListNode*)malloc(sizeof(ListNode));
    node->data = data;
    node->next = NULL;
    return node;
}

void addListNode(ListNode* list, ListNode* newListNode){
    ListNode* current;

    if(list == NULL){
        list = newListNode;
    }else{
        current = list;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newListNode;
    }
}

int main(void) {
    int ii;
    ListNode* list = NULL;
    ListNode* newListNode = NULL;
    int fakeData[3] = {1, 2, 3};

    for(ii=0; ii<=2; ii++){
        newListNode = createListNode(fakeData[ii]);
        addListNode(list, newListNode);
    }

    printf("%d", list->data);
    printf("%d", list->next->data);
    printf("%d", list->next->next->data);

    return 0;
}

When stepping through the code with a debugger, addListNode works as expected in a local context however, when returning to main the changes are lost and list is still equal to NULL. But list is defined in main so it should be in scope and available until that function ends. Right?

If I make a small change to main like this.

for(ii=0; ii<=2; ii++){
    if(ii==0){
        list = createListNode(fakeData[ii]);
    }else{
        newListNode = createListNode(fakeData[ii]);
        addListNode(list, newListNode);
    }
}

It works fine. Why would that be?

I could do it like this, but I don't want to have linked list specific code floating everywhere.

Clearly, I'm missing something quite fundamental.

Was it helpful?

Solution

void addListNode(ListNode* list, ListNode* newListNode)

This should be ListNode **list, otherwise the function really won't change it's value. The list = newListNode; command won't have any effect outside the function.

Use ListNode **list, and when you want to change the value just say *list = newListNode;

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top