这是我上一个问题的后续内容: C++ full system crash, release mode only
基本上我有一个树状的数据结构,在Release模式下,它完全冻结了操作系统。这是由于内存分配突然激增,超出了操作系统可以处理的范围。
这看似内存泄漏(它是,但在一分钟内更多)是非常奇怪的,因为我有所有必要的代码来初始化指向NULL并最终分配它们(必要时)如果它们被发现是NULL。在调试模式下,确认了这个正确的行为,并且事情分配正常(我可以看到调试器中的NULL指针设置为零)。
但在发布模式中,情况有所不同。构造函数被完全跳过,并且所有类的内部都被初始化为随机垃圾。这会导致指针变得混乱,这就是内存被分配的地方,直到整个系统崩溃。
为什么Release模式会忽略我的构造函数?
我在Windows 7上使用Visual Studio 2010顺便说一句。
答案 0 :(得分:5)
从(不完整的)代码判断:
template <class NodeData> struct OctNode {
OctNode() {
for (int i = 0; i < 8; ++i)
children[i] = NULL;
}
~OctNode() {
for (int i = 0; i < 8; ++i)
delete children[i];
}
OctNode *children[8];
vector<NodeData> data;
};
将OctNode
分配给另一个时,可能会泄漏内存。编译器生成默认的复制构造函数和赋值运算符。后者可能会导致内存泄漏,因为它不会释放先前分配的内存。我建议将类定义更改为以下内容:
template <class NodeData> struct OctNode {
OctNode() : children() {} // zero-initialize children
~OctNode() {
for (int i = 0; i < 8; ++i)
delete children[i];
}
OctNode *children[8];
vector<NodeData> data;
private:
OctNode(OctNode const&);
OctNode& operator=(OctNode const&);
};
编译代码。如果因为OctNode& operator=(OctNode const&)
是私有的而无法编译,则会导致泄漏。
答案 1 :(得分:3)
您指向的示例代码(http://www.cmlab.csie.ntu.edu.tw/~wildmb/pbrt/octree_8h-source.html)具有管理原始指针的struct OctNode
类,而没有适当的复制构造函数或赋值运算符(或者已禁用它们)。
class Octree
包含struct OctNode
的实例,因此如果您复制/分配了Octree
个对象,则堆很可能会被损坏。
将以下内容添加到struct OctNode
以禁用复制和分配,并查看是否开始出现链接器错误:
private:
OctNode(const OctNode&);
OctNode& operator=(const OctNode&);
但是,我不能给出一个很好的理由,为什么这不会导致你的调试版本出现问题,所以我很怀疑这实际上是你麻烦的根源。