I got a school project where I need to sort numbers using linked list. I had some trouble initializing my linked list and someone gave me the folllowing solution, but I don't really understand what is happening on a line and I would like some enlightenment.
Here's the full function :
void stack_ini(t_lst **list_ptr, char **nbr)
{
for (; *nbr; nbr)
{
// Create a new node.
t_lst *node = malloc(sizeof(t_lst));
node->content = ft_atoi(*nbr);
node->next = NULL;
// Insert it into the list.
*list_ptr = node;
list_ptr = &node->next;
}
}
To complete, here's the t_lst struct :
typedef struct s_lst
{
int content;
int position;
int index;
struct s_lst *next;
} t_lst;
I pretty much understand everything that's happening before the last line :
list_ptr = &node->next;
I dont get why I need to assign list_ptr to the adress of node->next. Isnt node->next supposed to be uninitialized and thus provoke a segfault ? Also, if node and list_ptr are unassigned to their ...->next, shouldnt it just be like overwritting their current value ?
Sorry for my english and thanks for your answers.
CodePudding user response:
I pretty much understand everything that's happening before the last line :
list_ptr = &node->next;
I dont get why I need to assign list_ptr to the adress of node->next. Isnt node->next supposed to be uninitialized and thus provoke a segfault ?
No. node->next
is explicitly initialized to a null pointer. Moreover, even if it were not initialized, its address (&node->next
) is well defined. That can be computed regardless of the initialization status or value of node->next
.
Dereferencing node->next
at that point (*node->next
) would produce undefined behavior as a result of its value being a null pointer, and that might very well manifest as the program crashing with a segfault, but no dereference is being performed.
Also, if node and list_ptr are unassigned to their ...->next, shouldnt it just be like overwritting their current value ?
After adding a node, list_ptr
is set to point to that node's next
member, whose value is initially null. Then when the next node is created, a pointer to it is assigned through list_ptr
to the (then-)previous node's next
. Afterward, the cycle repeats, starting with updating list_ptr
to point to the next
member of the most recently added node.
So yes, assigning through list_ptr
does replace the value of the pointer to which it points, but that happens at most once for each node, because after that update, list_ptr
is itself updated to point to the next
member of a different node.
CodePudding user response:
Let's assume that initially the pointer to the head node declared in main is set to NULL something like
t_lst *head = NULL;
This pointer is passed to the function stack_ini
by reference indirectly through pointer to it. So the function is declared like
void stack_ini(t_lst **list_ptr, char **nbr);
^^^^^^^^^^^^^^^^
Dereferencing the parameter list_ptr
the first time like *list_ptr
we get an access to the original pointer head
declared in main and can change it.
So within the function in the first iteration of its for loop this statement
*list_ptr = node;
sets the original pointer head
to the value of the pointer node
that points to the newly allocated node..
Then the parameter list_ptr
is set to the address of the data member head->next
which is equivalent to using node->next
in this statement
list_ptr = &node->next;
So now the pointer list_ptr
points to the data member next
that can be changed in the next iteration of the for loop.
The data member node->next
is initialized
node->next = NULL;
That is in this statement
list_ptr = &node->next;
you are not assigning the value of the data member node->next to the pointer list_ptr
. Instead the pointer list_ptr
points to the data member next
of the current created node and using list_ptr
you can change the value that data member in the next iteration of the for loop.