在Win32调试版本中,什么可以导致VTable指针为0xdddddddd?

时间:2011-04-19 07:38:17

标签: c++ debugging vtable

我正在调试一个缺陷,并将其缩小到对象为0xdddddddd的vtable指针。 This answer表示Win32调试版本通常会将死记忆或已删除的内存设置为此特殊值。

请注意,指针本身看起来有效,它只是 vtable指针,即0xdddddddd

以下是一段代码:

std::list<IMyObject*>::const_iterator it;
for (it = myObjects.begin(); it != myObjects.end(); ++it)
{
    IMyObject* pMyObject = *it;
    if (pMyObject == 0)
        continue;

    pMyObject->someMethod(); // Access violation     
}

如果我突破访问冲突的行并观看pMyObject,我可以看到pMyObject本身有一个有效的地址(0x08ede388),但__vfptr成员无效(0xdddddddd)。

一些注意事项:

  • 这是一个单线程应用程序,所以这很可能不是竞争条件或互斥问题。
  • 在访问对象之前,似乎没有任何明显的问题,例如在对象堆栈中进一步删除对象。
  • 此问题似乎只能在Windows 2008服务器上重现,但不能在Windows 7上重现。

有关如何进一步调试的任何建议吗?

4 个答案:

答案 0 :(得分:9)

释放后使用指针。从析构函数中的断点获取堆栈跟踪以查看删除它的内容。或者更好的是,使用shared_ptr&lt;&gt;避免这个问题。

答案 1 :(得分:1)

如果启动程序,请在创建对象的位置放置断点。然后添加内存断点。如果您覆盖或删除内存,则会触发此操作。好吧,或以任何方式改变它。

如果内存未被覆盖,您的对象看起来会正确,但您的vtable可能不依赖于编译器细节。

如果使用继承,这也可能是一个大小问题。如果您使用任何类型的存储桶存储器或通过指针以外的任何方式存储对象。

答案 2 :(得分:1)

如果pMyObject-&gt; someMethod()最终修改myObjects列表,它将使任何当前迭代器无效。

此外,如果指针数据已被删除,则会触发相同的问题。

答案 3 :(得分:1)

好的哇,所以我已经用c ++编程多年了,直到现在才发现这个...实际上有魔术数字/魔术调试值你可以查找什么& #39;在调试时继续使用原始指针!

见这里:In Visual Studio C++, what are the memory allocation representations?

在这里:https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_debug_values