Reputation: 1
I'm trying to implement a dynamic template queue in c++, but when I call the destructor I get a "double free or corruption (out)" error. Unfortunately I'm not allowed to change the file structure, or add any new methods/classes, or change the class/method declerations. I tried adding 5 items to a queue(rq1), before printing it out and destructing it, the print works fine, but I get an error when I destruct. Here is my code:
#include "resrcQueue.h"
#include <string>
#include <iostream>
using namespace std;
int main(){
queueNode<string>* q1 = new queueNode<string>("apples",100);
queueNode<string>* q2 = new queueNode<string>("lemons",200);
queueNode<string>* q3 = new queueNode<string>("gold",10);
queueNode<string>* q4 = new queueNode<string>("stone",11);
queueNode<string>* q5 = new queueNode<string>("brick",12);
resrcQueue<string> rq1;
rq1.enqueue(q1);
rq1.enqueue(q2);
rq1.enqueue(q3);
rq1.enqueue(q4);
rq1.enqueue(q5);
rq1.print();
delete &rq1;
return 0;
}
#ifndef RQUEUE
#define RQUEUE
#include <string>
#include <iostream>
#include "queueNode.h"
using namespace std;
template <class T>
class resrcQueue{
private:
queueNode<T>* head;
queueNode<T>* tail;
public:
resrcQueue();
~resrcQueue();
void enqueue(queueNode<T>* t);
void dequeue();
queueNode<T>* peek();
void print();
int tallyWeight();
string calculateStorageRequirements();
};
#include "resrcQueue.cpp"
#endif
#include "resrcQueue.h"
#include <string>
#include <iostream>
using namespace std;
template <class T>
resrcQueue<T>::resrcQueue(){
head=NULL; tail=NULL;
}
template <class T>
resrcQueue<T>::~resrcQueue(){
queueNode<T>* currNode=head;
queueNode<T>*temp;
int count=1;
while(head){
cout<<count<<endl;
this->dequeue();
count++;
}
}
template <class T>
void resrcQueue<T>::enqueue(queueNode<T>* t){
queueNode<T>*newNode=NULL;
newNode = new queueNode<T>(t->getResrc(),t->getWeight());
if(head){//not empty
tail->next=newNode;
tail=newNode;
}else{//empty
head=newNode;
tail=newNode;
}
}
template <class T>
void resrcQueue<T>::dequeue(){
if(head){//not empty
queueNode<T>* temp=head;
head=head->next;
delete temp;
}else{//empty
cout<<"EMPTY"<<endl;
}
}
template <class T>
queueNode<T>* resrcQueue<T>::peek(){
return head;
}
template <class T>
void resrcQueue<T>::print(){
queueNode<T>* currNode=head;
while(currNode){
cout<<"Resource: "<<currNode->getResrc()<<endl;
cout<<"Quantity: "<<currNode->getWeight()<<endl;
currNode=currNode->next;
}
}
template <class T>
int resrcQueue<T>::tallyWeight(){
int totalWeight=-1;
if(head){
totalWeight=0;
queueNode<T>* currNode=head;
while(currNode){
totalWeight+=currNode->getWeight();
currNode=currNode->next;
}
}
return totalWeight;
}
template <class T>
string resrcQueue<T>::calculateStorageRequirements(){
int numNodes=0;
queueNode<T>* currNode=head;
while(currNode){
numNodes++;
currNode=currNode->next;
}
string r;
if(this->tallyWeight()<100){
r="wooden crate";
}else if(this->tallyWeight()>200 && numNodes>5){
r="steel crate";
}else if(numNodes>5){
r="silo";
}else{
r="LOGISTICS ERROR";
}
return r;
}
#ifndef QNODE
#define QNODE
#include <string>
#include <iostream>
using namespace std;
template <class T>
class queueNode{
private:
T resrc;
int weight;
public:
queueNode* next;
queueNode(T r, int w);
~queueNode();
T getResrc();
int getWeight();
};
#include "queueNode.cpp"
#endif
#include <string>
#include <iostream>
#include "queueNode.h"
using namespace std;
template <class T>
queueNode<T>::queueNode(T r, int w){
next=NULL;
resrc=r; weight=w;
//cout<<"Init with weight: "<<weight<<", and resource: "<<resrc<<endl;
}
template <class T>
queueNode<T>::~queueNode(){
cout<<"Resource Unit Destroyed"<<endl;
}
template <class T>
T queueNode<T>::getResrc(){
return resrc;
}
template <class T>
int queueNode<T>::getWeight(){
return weight;
}
main.out: main.cpp queueNode.h queueNode.cpp
g++ -static -g main.cpp -o main.out
run: main.out
./main.out
clean: main.out
rm main.out
Apologies if the question is a little specific and if I included too much code, I couldn't manage to duplicate the error which is why I posted the original code where I got the error, and I did struggle quite a lot of hours to fix it myself before posting it here, I will decrease the code length if it'll be better that way.
Upvotes: 0
Views: 323
Reputation: 3433
There's a reason we ask people to make a MCVE - in the process of doing this you'll probably find the answer to your question.
When you take your program and strip out ALL of the unnecessary code and consolidate it into one file that still exhibits the bug, you get something like this:
#include <string>
using namespace std;
template <class T>
class resrcQueue{ };
int main(){
resrcQueue<string> rq1;
delete &rq1;
}
This still exhibits the bug. The reason for this is you can't delete stack variables. Remove the delete statement.
#include <string>
using namespace std;
template <class T>
class resrcQueue{ };
int main(){
resrcQueue<string> rq1;
}
Upvotes: 3