Search code examples
clinked-listdynamic-memory-allocation

Head of a simple linked list changing


Hello guys I am trying linked list implementation in C language

I do by so In my linked_list.h file I have

struct Node{
    void *data;
    struct Node *next;
};
struct LinkedList{
    struct Node* head;
};

And its implementation linked_list.c

struct LinkedList* Create_linked_list(){
    struct LinkedList* linked_list = (struct LinkedList*)malloc(sizeof(struct LinkedList));
    return linked_list;
}

struct Node* Get_last_node(struct LinkedList* linked_list){
    struct Node *temp = linked_list->head;
    while(temp->next != NULL){
        temp = temp->next; 
    }

    return temp;
}

struct Node* Get_node_at(struct LinkedList* linked_list,int position){
    if(position >= get_size(linked_list)){
        return NULL;
    }else{
        struct Node *temp = linked_list->head;
        int i;
        for(i=0;i< position;i++){
            temp = temp->next;
        }
        return temp;
    }
}

void Append_node(struct LinkedList* linked_list,void *data){
    struct Node *new_node = (struct Node*)malloc(sizeof(struct Node));
    new_node->data = data;
    new_node->next = NULL;
    if(linked_list->head == NULL){
        linked_list->head = new_node;
    }else{
        struct Node *last_node = Get_last_node(linked_list);
        last_node->next = new_node;
    }   
}

int get_size(struct LinkedList* linked_list){
    struct Node* temp = linked_list->head;
    int length;
    while(temp != NULL){
        length++;
        temp = temp->next;
    }
    return length;
}


void Delete_linked_list(struct LinkedList* linked_list){
    free(linked_list->head);
    free(linked_list);
}

and in my main.c

int main(int argc,char *argv[]){
    struct LinkedList *linked_list = Create_linked_list();

    int i;
    for(i=1;i<=10;i++){
        Append_node(linked_list,(void*)&i);
    }
    struct Node *node_n = Get_node_at(linked_list,1);
    printf("%d\n",*(int*)node_n->data);

    Delete_linked_list(linked_list);
    return 0;
}

I have two questions:

1) I get the output as 11
It means that the head is changing in the recursion.
What is the reason for this?

2)Is it necessary to free the memory by

free(linked_list->head);
  free(linked_list);

or only free(linked_list); is sufficient?


Solution

  • The output is 11 because you are inserting the same pointer into every node, and they all point to &i, which ends up at value 11 after the for loop. If you wanted to store the integers 1..10 into the linked list, you would need to cast your integers to void *. Here is your main() function rewritten to do this:

    #include <stdint.h>
    
    int main(int argc,char *argv[]){
        struct LinkedList *linked_list = Create_linked_list();
    
        int i;
        for(i=1;i<=10;i++){
            // Notice: store integer casted to void *
            Append_node(linked_list,(void*)(intptr_t) i);
        }
        struct Node *node_n = Get_node_at(linked_list,1);
        // Notice: cast the void * back to integer.
        printf("%d\n", (int)(intptr_t) node_n->data);
    
        Delete_linked_list(linked_list);
        return 0;
    }
    

    As for the question of deletion, not only do you need to free linked_list and linked_list->head, you also need to free every node in the linked list, otherwise you will be leaking memory.

    void Delete_linked_list(struct LinkedList* linked_list){
        struct Node *p = linked_list->head;
    
        while (p != NULL) {
            struct Node *next = p->next;
            free(p);
            p = next;
        }
    
        free(linked_list);
    }