Home > Software engineering >  Appending node to the end of a linked list in C; infinite loop problem
Appending node to the end of a linked list in C; infinite loop problem

Time:09-02

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;
}
  • Related