4

我们收到了来自客户站点的故障转储。我看到在 nstack 上的一个结构中,__vfptr 是 NUL。

它是否总是指向有问题的条件(内存溢出,删除对象两次......)或者是否存在此指针可以为空的情况。

4

5 回答 5

15

您是否在类实例的任何地方使用 memset() ?

我以前见过这个问题,原因是这样的代码

C类:SomeClassWithVirtualFunctions
{
上市:
  C()
  {
    memset(这个,0,sizeof(C));// 坏的!!也将 _vfptr 设置为 0
  }
}

cppcheck很整洁

于 2009-06-14T13:31:54.947 回答
6

您可能会在堆栈上看到部分损坏的对象。编译器可以通过清除虚函数表指针将对象的一部分标记为已销毁,以便它可以正确实现具有“钻石”继承(具有公共虚拟基类的类的多重继承)的类的析构函数如果程序崩溃在对象销毁期间,您将在转储中看到部分销毁的对象。

旧的 MSVC 编译器没有正确地为具有菱形继承的类实现析构函数。任何时候你试图摧毁一个,程序就会崩溃。我不确定是否仍然如此。

于 2009-06-14T16:16:29.387 回答
1

虽然通常答案是“是”,但我认为您应该考虑这也可能是调试器故障。

于 2009-06-14T13:30:01.567 回答
1

如果您尝试在typeid没有虚函数的类的对象上获取运行时类型信息(即使用函数),就会发生这种情况。

于 2009-06-14T14:48:58.803 回答
0

通常,当对象被删除两次时,我会得到 vptr 损坏(是的,它总是一个错误)。大多数时候对我来说,vptr 只是指向一些随机的内存块,但听起来你的被 NULL 覆盖了,这可能是操作系统清除了回收的内存,或者它可能是一个指向正在做什么的指针覆盖。

考虑使用boost::shared_ptr来维持所有权的生命周期。

于 2009-06-14T14:37:37.160 回答