新对象导致堆上的损坏

reu*_*cam 2 c++ heap gflags

几天来,我一直在努力解决堆腐败问题.我第一次被vs 2005调试器警告我可能已经损坏了堆,删除了我以前新建的对象.对这个问题进行研究后,我得到了gflags和页面堆设置.为我的特定图像启用此设置后,它应该指向我实际导致损坏的行.

Gflags将相关对象的构造函数识别为罪魁祸首.该对象派生如下:

class POPUPS_EXPORT MLUNumber :  public MLUBase
  {
...
  }
class POPUPS_EXPORT MLUBase : public BusinessLogicUnit
  {
...
  }
Run Code Online (Sandbox Code Playgroud)

我可以在一个单独的线程中实例化一个MLUNumber,并且不会发生堆损坏.

我可以实例化一个不同的类,它也继承自MLUBase,不会导致堆损坏.

由于在构造函数的左括号上发生损坏而导致访问冲突,这似乎是由于对象的隐式初始化(​​?).

基类构造函数(MLUBase)成功完成.

从vs 2005中的内存窗口挖掘,似乎没有为实际对象分配足够的空间.我的猜测是,只为基类分配了足够的内容.

导致故障的线路:

BusinessLogicUnit* biz = new MLUNumber();
Run Code Online (Sandbox Code Playgroud)

我希望有任何可能导致这种情况的原因,或者其他故障排除步骤.

bdo*_*lan 6

不幸的是,根据给出的信息,无法明确诊断问题.

您可能想要检查的一些事项:

  • 确保BusinessLogicUnit具有虚拟析构函数.当delete通过基指针执行对象时,必须在基类中存在虚拟析构函数,以便正确地销毁子类.
  • 确保使用相同的预处理程序标志和编译器选项构建所有源文件.标志的差异(可能在调试/释放标志之间?)可能导致结构大小的变化,从而导致在不同源文件中报告的大小之间的不一致.
  • 即使使用gflags设置,也可能无法检测到某些类型的堆损坏.审核您的其他堆使用以尝试查找问题的来源.理想情况下,您应该将最小的测试用例放在一起,这个测试用例会可靠地崩溃,但只需要最少量的活动,因此您可以缩小原因.
  • 尝试一个干净的解决方案并重建; 我偶尔会看到时间戳搞砸了,旧的目标文件可以使用过时的结构定义.值得检查至少:)

  • 最后的答案是 dll 之间的字节对齐方式不同,而 exe 从该 DLL 中提取标头。这实际上来自 #pragma pack 语句,而不是编译器选项。#pragma pack(show) 把我引向了罪魁祸首。这与你的子弹 2 很接近,所以你得到了信任。谢谢 (2认同)