Home > Software design >  Why is my list->next pointer affected by free()?
Why is my list->next pointer affected by free()?

Time:09-12

I'm trying to implement a linked list and adding nodes to it. I encountered the following problem, when I try to free the pointer n after setting list->next to point to the same address of n, the int value inside the second node also changes to garbage value when I print it again. I want to know if inside the memory, n and list->next is stored as two separate pointers that hold the same value or it is stored as a single pointer? And if they were distinct, then why freeing n also affect list->next? Furthermore if freeing n make the second node became lost, then why I can still use the list->next->next pointer to add a third node, was list->next->next pointer also some random value that points to a random usable location ? Here is my code, sorry if my question is too vague, I'm trying my best to understand all this pointers.

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>

typedef struct node {
    int number;
    struct node *next;
} node;

int main(void) {
    node a;
    a.number = 1;
    a.next = NULL;
    node *list = NULL;
    list = &a;           // the first node
    printf("%i \n", a.number);

    node *n = malloc(sizeof(node)); // creating pointer to the second node
    if (n != NULL) {
        n->number = 2;
        n->next = NULL;
    }

    list->next = n; // add the node to the list

    printf("%p \n%p \n", n, list->next);   // print out the address and value
    printf("%i \n", list->next->number);

    free(n);

    printf("%p \n%p \n", n, list->next);   // print out the address and value
    printf("%i \n", list->next->number);

    n = malloc(sizeof(node));

    printf("%p \n%p \n", n, list->next);
    if (n != NULL) {
        n->number = 3;
        n->next = NULL;
    }
    list->next->next = n;
    printf("%i\n", (*(*(*list).next).next).number);
    return 0;
}

Here is the output

1 
0x5562319d62a0 
0x5562319d62a0 
2 
0x5562319d62a0 
0x5562319d62a0 
1445140950 
0x5562319d62a0 
0x5562319d62a0 
3

CodePudding user response:

The assignment

list->next = n

doesn't copy the allocated memory. It just add another pointer pointing to the same memory.

If we "draw" it, before the assignment it looks something like this:

 ---        ----------------- 
| n | ---> | memory for node |
 ---        ----------------- 

Then after the assignment you have:

 ---      
| n | -----------\
 ---             |      ----------------- 
                  >--> | memory for node |
 ------------    |      ----------------- 
| list->next | --/
 ------------ 

Then you pass n to free leading to this situation:

 ---      
| n | -----------\
 ---             |     
                  >--> ???
 ------------    |     
| list->next | --/
 ------------ 

After the call to free, the pointer list->next is invalid. Any attempt to dereference it will lead to undefined behavior.

  • Related