我正在处理一个包含数组queues
的对象,其数组长度在调用构造函数之前不会被确定。基本上它看起来像下面的
#include <queue>
class myClass{
public:
//public functions
private:
//private functions and variables
queue<int>* myQueue;
};
它初始化如下:
myClass::myClass(int numOfQueues){
myQueue = new queue<int>[numOfQueues];
}
这似乎很美妙。它的功能与我希望的完全一样,但现在每次退出程序时都会出现分段错误。该类中包含其他一些以相同方式初始化的数组,但这些数组的类型为bool
和int
而不是队列。我的析构函数看起来像:
myClass::~myClass(){
delete boolArray;
delete intArray;
delete myQueue;
}
现在我假设这个析构函数适用于boolArray
和intArray
指针,因为在添加myQueue
之前我没有开始出现段错误。有谁知道编写析构函数的正确方法是什么?是否有可能这就是我必须做的事情,并且析构函数在适当的时候没有被调用?
答案 0 :(得分:7)
因为您使用new[]
分配,所以您应该在析构函数中执行delete[] myQueue;
。否则它将调用未定义的行为。顺便说一句,如果您不想获得此类内存管理问题,可以使用std::vector<std::queue<int> >
。
答案 1 :(得分:3)
为什么不使用std::vector
而不是数组?
您需要delete[]
数组,而不是delete
- 您已分配new[]
答案 2 :(得分:1)
将delete
与new[]
一起使用不仅会导致内存泄漏,还会调用未定义的行为。
与delete
一起使用的new[]
的正确形式为delete[]
。
然而,在惯用的C ++中,始终建议使用std::vector
而不是使用C样式数组。使用STL容器时,无需自己明确管理内存。
答案 3 :(得分:0)
Naveen已经解决了这个问题。我想添加一个好的编程实践。
以下用例也会产生删除问题。
void foo()
{
myClass a;
myClass b(a);
}
当我们声明 a 时,将创建一个新的myQueue实例。但是,在声明 b 时,将调用复制构造函数而不是 myClass :: myClass(int numQueues)构造函数。因此 a .myQueue == b .myQueue 。
当退出函数 foo 时, a 的析构函数将删除 myQueue ,然后 b 的析构函数将尝试删除未引用的指针,这会导致致命的错误。
一个好的编程习惯是相应地实现复制构造函数和 = operator ,或者声明复制构造函数和 = operator < / em> 私人以避免此类问题。
private:
myClass(const myClass&);
const myClass& operator=(const myClass&);
另请参阅 boost :: NonCopyable