Jeremy
Jeremy

Reputation: 201

"Aborted (core dumped)" error in dequeue method of queue class

This queue class's dequeue method doesn't work properly and I'm not sure why. When I run it it says "* Error in `./a.out': double free or corruption (fasttop): 0x00000000018dfe50 *", followed by a backtrace and then "Aborted (core dumped)".

At first I was deleting the bottom node directly, but I thought that might be the problem so I switched to deleting them another way.

Here's the dequeue method:

int Queue::dequeue() {
  if (isEmpty()) {
    cout << "ERROR: Can't dequeue from empty Queue"<< endl;
    return -1;
  } else {
    Node* n = top;
    if (n == NULL){
      bottom = top;
      return 0;
    }
    if (n->next == NULL){
      delete n;
      bottom = top;
      return 0;
    }
    while(n->next->next != NULL){
      n = n->next;
    }
    bottom = n;
    n = n->next;
    delete n;
    return 0;
  }
}

And here's the whole file:

  #include <iostream>
  using namespace std;

  struct Node {
      int data;
      Node *next;
  };

  class Queue {
  public:
      Queue(); //constructor
      ~Queue(); //destructor
      void enqueue(int d); //enqueues node onto top of Queue
      int dequeue(); //dequeues bottom node off of Queue -- returns integer dequeued
      bool isEmpty(); //checks if Queue is empty
      void print(); //print contents of Queue from top to bottom

  private:
      Node* top; //points to top node in Queue
      Node* bottom; //points to bottom node in Queue
  };

  Queue::Queue() {
      top = NULL;
      bottom = NULL;
  }

  Queue::~Queue() {
    while (!isEmpty())
      dequeue();
  }

  void Queue::enqueue(int d) {
    Node* temp = new Node;
    temp->data = d;

    temp->next = top;
    top = temp;

    if (temp->next == NULL){
      delete bottom;
      bottom = temp;
    }
  }

  int Queue::dequeue() {
    if (isEmpty()) {
      cout << "ERROR: Can't dequeue from empty Queue"<< endl;
      return -1; //error
    } else {
      Node* n = top;
      if (n == NULL){
        bottom = top;
        return 0;
      }
      if (n->next == NULL){
        delete n;
        bottom = top;
        return 0;
      }
      while(n->next->next != NULL){
        n = n->next;
      }
      bottom = n;
      n = n->next;
      delete n;
      return 0;
    }
  }

  bool Queue::isEmpty() {
    return (top==NULL);
  }

  //Print Queue from top to bottom
  void Queue::print(){
    Node* n = top;
    while(n != NULL){
      cout << n->data << endl;
      n = n->next;
    }
    cout << endl;
  }

  int main(){
      Queue* s = new Queue();
      s->print();
      s->enqueue(20);
      s->enqueue(30);
      s->print();
      s->enqueue(40);
      s->enqueue(12);
      s->print();
      s->dequeue();
      s->print();
      s->dequeue();
      s->print();
      s->dequeue();
      delete s;

      return 0;
  }

Upvotes: 0

Views: 128

Answers (1)

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32732

Whenever you delete a node, you need to update all the pointers that point to the node being deleted. You need to do this in two places.

First, in the n->next == NULL case, the Queue only has one node. After you call delete n, top still points to this now deleted node, and you need to update top (to NULL or nullptr) before changing the value of bottom.

In the last case, where there is more than one node in the list, you delete the last node but the next pointer of the previous node still points to it. After the n = n->next expression, you need to set bottom->next to point to the node that n->next now points to (which, since n is the last node in the Queue, is NULL).

Upvotes: 1

Related Questions