2011-12-02 70 views
0

我有一个B类,它继承了带有一些虚函数的类A. B类也有一个虚拟函数(foo),似乎没有地址。当我用调试器走时,它指出foo有0x00000000地址,当我尝试加入时,它将在0x00000005处因访问冲突而失败。如果我让这个函数不是虚拟的,调试器就会进入并且工作正常,直到我达到std::vector。在我拨打push_back时,它将在地址0x000000005处出现相同的访问冲突,同时在地址0xabababab处写入一些内容,并且调用堆栈指向插入函数中的互斥锁。C++罕见的运行时错误

注意:我没有使用任何其他线程,每次编译时增量链接器都会崩溃。只有完整的链接器才能成功创建exe。编译器来自Visual Studio 2008专业版,当解压出未使用的源文件和源代码时,就会出现此问题。

不幸的是,我无法恢复到以前的状态,以便发现创建这个的变化。

如何在不恢复整个项目的情况下检测问题的根源?也有人遇到这种错误,也许这可能是同一原因。

+7

给我们一些代码。 –

+2

最可能的原因是您通过空指针调用成员函数。 – sharptooth

+0

我正在使用调试器,但它未能给我任何相关信息。指针不为空,不幸的是我不能给你任何源代码。 – Raxvan

回答

2

你猜虚拟表已经坏掉了,但这不太可能,因为vtables通常存储在只读存储器中。

我能想到的两个原因针对此行为:

  • 您正在使用的对象已被删除。如果对象曾经是内存的话,它可能会偶然运行,但如果它被覆盖,它会失败。
  • 您使用的对象不是动态类型B.也许它是A型或可能是不相关的类型。

我已经成功地跟踪这类问题与的printf调试:在B,析构函数,虚函数和失败函数的构造与printf("XXX %p", this);添加了几行,你就可以推断发生了什么。

是的,我知道,的printf调试是不是很酷...

+0

感谢您的帮助:) – Raxvan

2

您正在调用空指针的虚函数。编译器添加将在对象中使用隐藏指针的代码来定位什么是最终覆盖,并且该操作失败。当您将该函数更改为非虚拟时,该调用将静态分派,但同样,由于this指针为空,因此对成员的访问将失败。

您应该检查您在代码中调用方法的对象的有效性。

+0

该对象对非空指针有效 – Raxvan

+0

@Raxvan:尝试在非虚拟版本内打印'(void *)this'并查看它打印出来的内容。 –

+0

发现错误,未创建类B。该指针应该保持类B,但它拥有一些其他类。 – Raxvan