dlistint_t *add_dnodeint_end(dlistint_t **head, const int n)
{
dlistint_t *head_ref, *new;
new = malloc(sizeof(dlistint_t);
if (!new)
return (NULL);
new->n = n;
new->next = NULL;
new->prev = NULL;
if (!(*head))
{
*head = new;
return (new);
}
head_ref = *head;
while (head_ref)
{
if (!head_ref->next)
{
head_ref->next = new;
new->prev = head_ref;
/* I need clarity here */
head_ref = head_ref->next;
}
head_ref = head_ref->next;
}
return (new);
}
The function adds a new node to the end of a doubly linked list but my problem is with the if
block in while
loop.
If i remove the line head_ref = head_ref->next;
the while
loop runs infinitely. When i use a break;
statement, it doesn't work for all cases. My confusion now is that I expect the head_ref = head_ref->next;
statement outside the if
block to always execute even when the if-condition is met thus terminating the loop.
I thought to ask because i did not find an answer that explains this clearly. Please link me if you find any that explains this well.
CodePudding user response:
Where you have the comment /* I need clarity here */
, there should be a return new;
(or you should break out of the loop) as without it you'll make head_ref
NULL with head_ref = head_ref->next
and then the next (same) statement will make an invalid reference.
If is more natural to remove that if
block and put that logic after the loop, and have the loop condition such that it ends when you're at the tail node.
I would not call this variable head_ref
, because it stops being that "head" once you start looping. Maybe call it current
:
dlistint_t *add_dnodeint_end(dlistint_t **head, const int n)
{
dlistint_t *current, *new;
new = malloc(sizeof(dlistint_t)); // missing parenthesis
if (!new)
return NULL;
new->n = n;
new->next = NULL;
new->prev = NULL;
current = *head;
if (current == NULL)
{
*head = new;
return new;
}
while (current->next != NULL) // Exit loop when at tail
{
current = current->next;
}
current->next = new;
new->prev = current;
return new;
}