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.