Search code examples
cfunctionlinked-listqueuedynamic-memory-allocation

C - Queue using linked list | Code run forever at one point


This is my main.c:

int main()
{
Queue* list = initialize();
if (!isEmpty(list))
{
    fprintf(stderr, "Error!\n");
}

enqueue(list, 10);
enqueue(list, 20);
display(list);       // Output: 10 -> 20 -> nil

if (front(list) != 10)
{
    fprintf(stderr, "Error!\n");
}

if (back(list) != 20)
{
    fprintf(stderr, "Error!\n");
}

enqueue(list, 30);
display(list);       // Output: 10 -> 20 -> 30 -> nil

int len = length(list);
if (len == 3)
{
    fprintf(stdout, "Number of elements in Queue: %d.\n", len);
}
else
{
    fprintf(stderr, "Error!\n");
}

dequeue(list);
display(list);     // Output: 20 -> 30 -> nil

if (front(list) != 20)
{
    fprintf(stderr, "Error!\n");
}

if (back(list) != 30)
{
    fprintf(stderr, "Error!\n");
}

len = length(list);
if (len == 2)
{
    fprintf(stdout, "Number of elements in Queue: %d.\n", len);
}
else
{
    fprintf(stderr, "Error!\n");
}

empty(list);
display(list);    // Output: Queue is empty.
free(list);
return 0;
}

This is my queue.c:

    Queue* initialize()
{

  Queue* q = (Queue*)malloc(sizeof(Queue));
  q->front = q->back = NULL;
  return q;
}


struct Node* newNode(int item)
{
    Node* temp = (Node*)malloc(sizeof(Node));

    if (temp != NULL)
    {
        temp->value = item;
        temp->next = NULL;
        return temp;
    }
}


int enqueue(Queue* q, int item)
{
    Node *temp = newNode(item);
    temp->value = item;
    if (q->front == NULL)
        q->front = temp;
    else
        q->back->next = temp;

    q->back = temp;
    q->back->next = q->front;
    return item;
}

int dequeue(Queue *q)
{
    Node *temp = q->front;
    printf("\nRemoving %d", temp->value);

    q->front = q->front->next;

    if (q->front == NULL)
        q->back = NULL;

    int item = temp->value;
    free(temp);
    return item;
}

Queue* display(Queue *q)
{
    Node *temp;
    temp=q->front;
    if(temp==NULL)
      printf("\n The queue is empty");
    else
    {
      printf("\n");
      while(temp != q->back)
      {
         printf("%d -> ",temp->value);
         temp=temp->next;
      }
      printf("%d -> nil",temp->value);
   }
   return q;
}


int front(Queue *q)
{
  if ((q->front != NULL) && (q->back != NULL))
    return (q->front->value);
    else
      return -1;
}    

int back(Queue *q)
{
  if ((q->front != NULL) && (q->back != NULL))
   return (q->back->value);
    else
      return -1;
}


bool isEmpty(Queue *q)
{
  if((q->front == NULL) || (q->back == NULL))
   return -1;
    else
      return 0;
}

void empty(Queue *q)
{
  q->front = NULL;
  q->back = NULL;
}


int length(Queue *q)
{
  int count=0;
  if(q->front!=NULL){
        Node *temp = q->front;
        while(temp->next != NULL)
        {
            count++;
            temp = temp -> next;
        }
    }
    return count;
}

Output should look like this:

10 -> 20 -> nil  
10 -> 20 -> 30 -> nil  
Number of elements in Queue: 3.  
20 -> 30 -> nil  
Number of elements in Queue: 2.  
Queue is empty.

My output:

10 -> 20 -> nil  
10 -> 20 -> 30 -> nil

And here it keeps running forever until I manually terminate it. I have no idea why, can somebody help with this please? My length function could be wrong, but I don't know if it is the reason for the error & how to fix it. Also, the main.c is fix, I can't change anything in that. Thanks for helping and reading all of this.


Solution

  • When you enqueue, you create a circular list with this statement

      q->back->next = q->front;
    

    You don't need to set q->back->next, it should be and already is null because newNode() sets it to `null'.