首页 > 解决方案 > 调用析构函数后 C++ 动态模板队列“双重释放或损坏(出)”

问题描述

我正在尝试在 C++ 中实现一个动态模板队列,但是当我调用析构函数时,我得到一个“双重释放或损坏(输出)”错误。不幸的是,我不允许更改文件结构,或添加任何新方法/类,或更改类/方法声明。我尝试将 5 个项目添加到队列(rq1),在打印出来并销毁它之前,打印工作正常,但是当我销毁时出现错误。这是我的代码:

主文件

#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;
}

rsrcQueue.h

#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

resrcQueue.cpp

#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;
}

队列节点.h

#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

队列节点.cpp

#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

抱歉,如果问题有点具体,并且如果我包含太多代码,我无法复制错误,这就是为什么我在出现错误的地方发布原始代码,我确实花了很多时间来修复在将其发布到此处之前,我自己会减少代码长度,如果这样会更好的话。

标签: c++templatesdynamicqueue

解决方案


我们要求人们制作MCVE是有原因的——在此过程中,您可能会找到问题的答案。

当你把你的程序去掉所有不必要的代码并将它合并到一个仍然存在错误的文件中时,你会得到这样的结果:

#include <string>
using namespace std;

template <class T>
class resrcQueue{ };

int main(){
  resrcQueue<string> rq1;

  delete &rq1;
}

这仍然显示错误。原因是您不能删除堆栈变量。删除删除语句。

#include <string>
using namespace std;

template <class T>
class resrcQueue{ };

int main(){
  resrcQueue<string> rq1;
}

推荐阅读