使用:CodeBlocks 13.12,GNU GCC mingw32-g ++,Dr.Memory
所以我有一个用于制作矢量队列的任务(先进先出)。 我制作了程序,一切正常,但在作业中我们需要使用接口IQueue。此界面无法更改。
#ifndef IQUEUE_H
#define IQUEUE_H
template <typename T>
class IQueue {
public:
virtual void enqueue(const T& element) = 0;
virtual T dequeue() = 0;
virtual T front() const = 0;
virtual bool isEmpty() const = 0;
};
#endif
这是(部分)我的Queue.h,所以你得到了图片。
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
#include <string>
#include <stdexcept>
#include "iqueue.h"
using namespace std;
template <typename T>
class Queue : virtual public IQueue<T> {
public:
Queue();
Queue(int capacity);
Queue(int capacity, int capacity_increment);
~Queue();
Queue(const Queue<T> &original);
void operator=(const Queue<T> &original);
void enqueue(const T& element);
T dequeue();
T front() const;
bool isEmpty() const;
private:
T *items;
int nr_of_items;
int capacity;
void expand(); //expands the array if the nr_of_items is bigger than capacity
void freeMemory();
};
/*stuff*/
template<typename T>
Queue<T>::~Queue() {
this->freeMemory();
}
template<typename T>
void Queue<T>::freeMemory() {
delete[] this->items;
}
我在运营商中使用freeMemory(),这就是为什么它是一个单独的功能。
现在到了主要的
#include "iqueue.h"
#include "queue.h"
int main() {
IQueue<string> *sq = new Queue<string>();
/*Do stuff with the queue*/
IQueue<string> *sq2 = new Queue<string>();
sq2 = sq;
IQueue<int> *iq = new Queue<int>();
/*Do stuff with the queue*/
IQueue<int> *iq2 = new Queue<int>();
iq2 = iq;
/*how to delete?*/
return 0;
}
我测试过的事情:
删除sq;删除sq2;删除iq;删除iq2;在freeMemory()中使用cout它根本不会运行。
和以前一样但我测试了在IQueue中制作虚拟解构器。与freeMemory()中的cout一起运行一次然后崩溃。我得到4个无法访问的访问,2个无效的堆参数,2个内存泄漏。 不太了解这里发生的事情。
我们还没有使用过uniqe指针但是当我用Google搜索时,这被认为是一种很好的方法。但我需要一个很好的解释,让我的程序知道如何做到这一点。
尝试过矢量:: erase cplusplus.com link。 像这样的感觉是正确的方法,但是我只是在没有模板类&#34;的情况下得到错误&#34;矢量擦除。我已经包括了&lt;矢量&gt;。
任何可以指出我正确方向的答案都值得赞赏。关于为什么我尝试的东西没有工作的一般信息会很好,让我更好理解。 如果需要,我会编辑更多代码。
旁注:我们被告知你把throw(...)放在.h文件中,如果函数中有一个try catch异常,就像这样: virtual T dequeue()throw(...)= 0; 但我只是犯了错误,这是一种标准的做法吗?
答案 0 :(得分:0)
我注意到你的代码和要点是: 1)您正在使用指针。也就是说,您实际上是将一个指针指向另一个指针。因此,不会调用operator =()。记忆会在那里泄漏。 2)正如你在第一点所说,你正在删除sq,然后是sq2,两者都指向同一个内存。因此检测到堆损坏。 iq和iq2也是如此。 3)也使用虚拟析构函数。
答案 1 :(得分:0)
IQueue<string> *sq = new Queue<string>();
IQueue<string> *sq2 = new Queue<string>();
sq2 = sq;
第一次内存泄漏。你丢失了指向sq2对象的指针。
IQueue<int> *iq = new Queue<int>();
IQueue<int> *iq2 = new Queue<int>();
iq2 = iq;
第二次内存泄漏。与上述相同。
现在,如果删除指向iq1或iq2的指针,则会出现第三次泄漏,因为您的接口没有虚拟析构函数,因此不会调用实现中的析构函数。