Rhu*_*arb 11 c++ debugging destructor msvcrt visual-c++
我有一些代码在大型系统中崩溃.但是,代码基本上归结为以下伪代码.我已经删除了很多细节,因为我试图把它煮到骨头上; 我不认为这会错过任何重要的事情.
// in a DLL:
#ifdef _DLL
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP __declspec(dllimport)
#endif
class DLLEXP MyClass // base class; virtual
{
public:
MyClass() {};
virtual ~MyClass() {};
some_method () = 0; // pure virtual
// no member data
};
class DLLEXP MyClassImp : public MyClass
{
public:
MyClassImp( some_parameters )
{
// some assignments...
}
virtual ~MyClassImp() {};
private:
// some member data...
};
Run Code Online (Sandbox Code Playgroud)
和:
// in the EXE:
MyClassImp* myObj = new MyClassImp ( some_arguments ); // scalar new
// ... and literally next (as part of my cutting-down)...
delete myObj; // scalar delete
Run Code Online (Sandbox Code Playgroud)
请注意,正在使用匹配标量新标量和标量删除.
在Visual Studio(2008 Pro)中的Debug构建中,在Microsoft的<dbgheap.c>中,以下断言失败:
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
Run Code Online (Sandbox Code Playgroud)
靠近堆栈顶部的是以下项目:
mydll_d.dll!operator delete()
mydll_d.dll!MyClassImp::`vector deleting destructor'()
Run Code Online (Sandbox Code Playgroud)
我认为这应该是
mydll_d.dll!MyClassImp::`scalar deleting destructor'()
Run Code Online (Sandbox Code Playgroud)
也就是说,该程序的行为就像我写的那样
MyClassImp* myObj = new MyClassImp ( some_arguments );
delete[] newObj; // array delete
Run Code Online (Sandbox Code Playgroud)
地址pUserData是myObj自身的(与成员相对).该地址周围的内存如下所示:
... FD FD FD FD
(address here)
VV VV VV VV MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
FD FD FD FD AB AB AB AB AB AB AB AB EE FE EE FE
...
Run Code Online (Sandbox Code Playgroud)
其中四个VVs可能是虚函数表的地址,是MM...MM可识别的成员数据,其他字节是调试器放置的各种特殊标记(例如,FD FDs是对象存储周围的'保护字节').
在断言失败之前不久,我确实看到了VVs的变化,并想知道这是否是由于切换到基类的虚函数表.
我知道正在进行破坏的类层次结构中的错误级别的问题.这不是问题所在; 我的析构函数都是虚拟的.
我注意到微软的页面"BUG:错误的操作员删除调用导出的类" http://support.microsoft.com/kb/122675, 但这似乎是关于错误的可执行文件(错误的堆)试图承担销毁的责任数据.
在我的例子中,删除析构函数的错误"味道"似乎正在被应用:即向量而不是标量.
我正在尝试生成仍然存在问题的最小缩减代码.
但是,任何有助于如何进一步调查此问题的提示或技巧将非常感激.
也许这里最大的线索就是mydll_d.dll!operator delete()堆叠.我是否应该期待这一点myexe_d.exe!operator delete(),表明DLLEXPs已"丢失"?
我想这可能是双删除的一个实例(但我不这么认为).
有什么参考我可以阅读有关_CrtIsValidHeapPointer检查的内容吗?
听起来像这可能是分配一个堆并尝试删除另一个堆的问题.从dll分配对象时,这可能是一个问题,因为dll有自己的堆.从您显示的代码看起来似乎不是这个问题,但可能在简化中丢失了一些东西?在过去,我看到这样的代码destroy在对象上使用工厂函数和虚方法,以确保在dll代码中发生分配和删除.
| 归档时间: |
|
| 查看次数: |
12513 次 |
| 最近记录: |