Reputation: 201
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
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