I was writing a singly-linked list in C and cannot understand this following code.
#include <stdlib.h>
typedef struct ListNode {
int val;
struct ListNode* next;
} ListNode;
int main() {
/*Say I allocate this list to say 1->2->3->4->NULL*/
ListNode* node = malloc(sizeof(ListNode));
ListNode* n1 = node; // An ordinary pointer
ListNode* n_heap = malloc(sizeof(ListNode)); // A heap allocated pointer
n_heap = node->next; // 2->3->4->NULL
n1->next = NULL;
}
Now from the above example, I had assumed that n_heap
to be NULL
as well. But even after n1->next = NULL;
, n_heap
is still 2->3->4->NULL
. So is the node->next
copied to n_heap
? or is it that n_heap
now points to the original heap located node->next
, and the n1->next
now set to NULL
? Does this mean node
wasn't initially the owner of node->next
data?
CodePudding user response:
int main() { /*Say I allocate this list to say 1->2->3->4->NULL*/ ListNode* node = malloc(sizeof(ListNode));
node
is a pointer to dynamically allocated data. On a C implementation with a stack / heap distinction, that will be on the heap.
ListNode* n1 = node; // An ordinary pointer
n1
now points to the same dynamically-allocated data that node
does. It is no more or less "ordinary" than node
is.
ListNode* n_heap = malloc(sizeof(ListNode)); // A heap allocated pointer
(On success) n_heap
points to different dynamically allocated data. The pointer itself has the same scope and storage duration as node
and n1
, and is exactly as "ordinary" as they are.
n_heap = node->next; // 2->3->4->NULL
Now the memory to which n_heap
previously pointed is leaked, because no pointers to it remain. n_heap
points to the same memory that node->next
does. Which is the same memory that n1->next
does.
n1->next = NULL;
Now the value of the pointer object accessible as n1->next
(and also as node->next
) is set to NULL. This has no effect on the data to which that pointer object previously pointed, nor on variable n_heap
, which still points to the data in question.
}
Now from the above example, I had assumed that
n_heap
to beNULL
as well. But even aftern1->next = NULL;
,n_heap
is still2->3->4->NULL
.
You are failing to distinguish between pointer objects and the objects to which their values point. Assigning NULL
to n1->next
sets the value of one pointer object. It does nothing to the object to which the old pointer value pointed. It does nothing to other, distinct points to the same object. And on the other hand, n_heap
is not 2->3->4->NULL
, It is a pointer distinct from all those nodes, whose value points to the node containing 2
.
So is the node->next copied to n_heap?
Yes, that's what an assignment does, but not in the sense I think you mean. Again, assigning n_heap = node->next
copies the pointer value stored in node->next
to n_heap
. Those two distinct pointer objects then both contain values pointing to the same data.
or is it that
n_heap
now points to the original heap locatednode->next
, and then1->next
now set toNULL
?
Yes and no. Again, neither the object designated by n_heap
nor the onje designated by node->next
contain the data you are describing as 2->3->4->NULL
. Instead, they both contain the address of the node containing the first of those values.
Does this mean
node
wasn't initially the owner ofnode->next
data?
It depends on what you mean by "owner". Certainly neither node
nor *node
is a container of the data to which node->next
points. As the term "owner" is usually applied to pointers, it is about responsibility for freeing the pointed to data, not about storage layout. Responsibility to free is a question of data and control flow in the program, not a property of the data itself.