新对象会导致堆损坏
new object causes corruption on the heap
几天来,我一直在与堆损坏问题作斗争。vs2005调试器首先警告我,在删除了以前新建的对象后,我可能已经损坏了堆。对这个问题的研究让我想到了gflags和页面堆设置。在为我的特定图像启用此设置后,它应该会将我指向实际导致腐败的行。
Gflags将问题对象的构造函数标识为罪魁祸首。对象派生如下:
class POPUPS_EXPORT MLUNumber : public MLUBase
{
...
}
class POPUPS_EXPORT MLUBase : public BusinessLogicUnit
{
...
}
我可以在一个单独的线程中实例化一个MLUNumber,并且不会发生堆损坏。
我可以实例化一个不同的类,它也继承自MLUBase,不会导致堆损坏。
由于构造函数的左大括号上出现损坏而引发的访问冲突,这似乎是由于对象(?)的隐式初始化所致。
基类构造函数(MLUBase)已成功完成。
从2005年与2005年的内存窗口挖掘来看,似乎没有为实际对象分配足够的空间。我的猜测是,只为基类分配了足够的资源。
导致故障的线路:
BusinessLogicUnit* biz = new MLUNumber();
我希望这可能是由于某种原因造成的,或者接下来的另一个故障排除步骤。
不幸的是,根据所提供的信息,无法明确诊断问题。
你可能想检查的一些东西:
- 确保BusinessLogicUnit具有虚拟析构函数。当
delete
通过基指针处理对象时,基类中必须存在一个虚拟析构函数,才能正确地析构子类 - 确保使用相同的预处理器标志和编译器选项构建所有源文件。标志的差异(可能是调试/发布标志之间的差异?)可能会导致结构大小的变化,从而导致不同源文件中报告的大小不一致
- 某些类型的堆损坏可能未被检测到,即使使用gflags设置也是如此。审计您的其他堆使用,试图找到问题的根源。理想情况下,你应该把一个最小的测试用例放在一起,它会可靠地崩溃,但活动量最小,这样你就可以缩小原因
- 尝试一个干净的解决方案并重建;我偶尔会看到时间戳被搞砸,一个旧的对象文件可能会使用过时的结构定义。至少值得检查:)
BusinessLogicUnit* biz = new MLUNumber();
如何删除内存?使用基类指针?你把BusinessLogicUnit
的析构函数虚拟化了吗?它必须是virtual
。
class BusinessLogicUnit
{
public:
//..
virtual ~BusinessLogicUnit(); //it must be virtual!
};
否则,根据C++标准,通过基类指针删除派生类对象会调用未定义的行为。
BusinessLogicUnit不是MLUNumber。你为什么要这样分配?相反BusinessLogicUnit*biz=新BusinessLogicUnit();
或者你可能会这样做?
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)
发生后立即死亡。。
我同意bdonlan的观点,即目前还没有足够的信息来找出问题所在。这里有很多好的建议,但仅仅猜测应用程序崩溃的可能原因并不是解决问题的明智方法。
通过启用检测(pageheap)来帮助您缩小问题范围,您做了正确的事情。我会继续沿着这条路走下去,找出导致访问违规的确切内存地址(以及地址来自哪里)。
- 构造函数初始化和对象损坏
- 从本机代码返回到托管代码会损坏返回的对象
- 在向量中使用不带复制且没有 noexcept 移动构造函数的对象.实际损坏的内容以及我如何确认它
- 引用可能已损坏的静态对象
- 部分损坏的对象
- 对同一对象的多个shared_ptrs,一个已损坏
- C 用向量序列化对象会导致双重自由损坏
- 如何在不存在任何数据损坏风险的情况下序列化对象
- 对象, 在 Vector 中, 在'For Loop'初始化中损坏
- 我的 QNX/BB10 C++应用程序崩溃,一个简单的C++对象似乎已损坏
- 从映射中检索后,映射中的对象已损坏
- 删除对象(另一个..)时双重释放或损坏
- 多线程对象中的堆损坏
- 对象的c++内存副本出现损坏
- 对象周围的堆栈已损坏
- 在Visual Studio调试模式下运行时,c++对象引用已损坏
- 为什么在返回对象时堆损坏?
- 使用内存复制对象时出现双自由或损坏错误
- 从复制构造函数外部修改对象成员时导致向量内存损坏,但从复制构造函数内部修改时不会
- C++对象引用损坏