Динамическая очередь шаблонов C ++ "double free или коррупция (выход)" после вызова деструктора - PullRequest
0 голосов
/ 19 октября 2019

Я пытаюсь реализовать динамическую очередь шаблонов в c ++, но когда я вызываю деструктор, я получаю ошибку "double free или коррупция (выход)". К сожалению, мне не разрешено изменять структуру файла, добавлять новые методы / классы или изменять описания классов / методов. Я попытался добавить 5 элементов в очередь (rq1), прежде чем распечатать и уничтожить, печать работает нормально, но я получаю ошибку, когда уничтожаю. Вот мой код:

main.cpp

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

queueNode.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

queueNode.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;
}

makefile

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

Извинения, если вопрос немного конкретен и если я включил слишком много кода, я не смогуМне не удалось продублировать ошибку, поэтому я опубликовал исходный код, в котором получил ошибку, и мне пришлось потратить довольно много времени, чтобы исправить ее самостоятельно, прежде чем публиковать ее здесь, я уменьшу длину кода, если это будет лучшетаким образом.

1 Ответ

3 голосов
/ 19 октября 2019

Есть причина, по которой мы просим людей сделать 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...