我几天都在努力解决堆腐败问题。我第一次被vs 2005调试器警告我可能已经损坏了堆,删除了我以前新建的对象。对这个问题进行研究后,我得到了gflags和页面堆设置。在为我的特定图像启用此设置后,它应该指向我实际导致损坏的行。
Gflags将相关对象的构造函数识别为罪魁祸首。该对象派生如下:
class POPUPS_EXPORT MLUNumber : public MLUBase
{
...
}
class POPUPS_EXPORT MLUBase : public BusinessLogicUnit
{
...
}
我可以在单独的线程中实例化MLUNumber,并且不会发生堆损坏。
我可以实例化一个不同的类,它也继承自MLUBase,不会导致堆损坏。
由于在构造函数的左大括号上发生损坏而导致访问冲突,这似乎是由于对象的隐式初始化(?)。
基类构造函数(MLUBase)成功完成。
从使用vs 2005中的内存窗口挖掘,似乎没有为实际对象分配足够的空间。我的猜测是,仅为基类分配了足够的内容。
导致错误的行:
BusinessLogicUnit* biz = new MLUNumber();
我希望有任何可能导致此问题的原因或其他问题排查步骤。
答案 0 :(得分:6)
不幸的是,根据所提供的信息,无法明确诊断出问题。
您可能想要检查的一些事项:
delete
对象通过基指针时,基类中必须存在虚拟析构函数才能正确销毁子类。答案 1 :(得分:2)
BusinessLogicUnit* biz = new MLUNumber();
如何删除内存?使用基类指针?你有BusinessLogicUnit
虚拟的析构函数吗?它必须是virtual
。
class BusinessLogicUnit
{
public:
//..
virtual ~BusinessLogicUnit(); //it must be virtual!
};
否则,通过基类指针删除派生类对象会根据C ++标准调用未定义的行为。
答案 2 :(得分:0)
BusinessLogicUnit 不是 MLUNumber。你为什么这样分配?代替 BusinessLogicUnit * biz = new BusinessLogicUnit();
答案 3 :(得分:0)
或者你可能会这样做?
struct A
{
SomeType & m_param;
A(SomeType & param) : m_param(param)
{
...use m_param here...
}
};
A a(SomeType()); // passing a temporary by reference
然后这是未定义的行为,因为引用的临时在m_param(param)
发生后立即死亡。
答案 4 :(得分:0)
我同意bdonlan的说法,还没有足够的信息来弄清楚什么是错的。这里有很多好的建议,但只是猜测应用程序崩溃的可能原因并不是导致问题的明智方法。
通过启用检测(pageheap)来帮助您缩小问题范围,您已经做了正确的事情。我会通过找出导致访问冲突的确切内存地址(以及地址来自哪里)继续沿着这条路走。