派生类vtable已损坏?

时间:2010-12-21 01:45:46

标签: c++ vtable

在root中需要帮助导致vtable损坏问题(不确定是否发生了这种情况)。这是代码的简化版本。

class CBase
{
public:
    CBase()
    virtual ~CBase()
    virtual void base_virtual_fn1() = 0;
    virtual void base_virtual_fn2();
private:
    CData   _data;
};

class CDerived : public CBase
{
public:
    CDerived();
    virtual ~CDerived()
    virtual void base_virtual_fn1();
    virtual void base_virtual_fn2();
    virtual void derived_virtual_fn1();
    virtual void derived_virtual_fn2();
private:
    // Contains vectors , maps, integers, bools. 
};

当我创建一个CDerived实例并调用派生类虚函数时,称为derived_virtual_fn2,另一个函数被调用,即derived_virtual_fn1。

调用base_virtual_fnx没有问题。

这只发生在堆上创建的对象而不是本地对象。

这些类位于共享库中。我在Linux上使用gcc 3.4.2(SLES 10)。在任何此代码中都没有pragma pack指令,并且混合使用C和C ++代码(使用extern c)。 这可能是什么问题?

我忘了提到有很多其他代码(可执行文件,库)

5 个答案:

答案 0 :(得分:3)

这是我犯下的一个令人讨厌的错误,让我永远找到了。编译器/调试器/ valgrind没有让我知道发生了什么。应该有一些方法来调试这些错误:

基类是在定义了“SOME_PACKAGE”的库中编译的:

class interface {
    virtual int function1(int);
#ifdef SOME_PACKAGE
    virtual int function2(int);
#endif
    virtual int function3(int);
}

class base : public interface {
    int function1(int);
    int function2(int);
    int function3(int);
}

稍后编译派生类而没有定义SOME_PACKAGE

class derived : public base {
    int function1(int);
    int function3(int);
}

调用function3导致跳转到function2,我最终能够通过调试器找到它,但是我花了很长时间才找到原因。

答案 1 :(得分:1)

如果只发生在堆上创建的对象,最可能的解释是堆损坏,这可能与您提到的两个类无关。检查您的分配/解除分配!检查你是否正确使用delete []删除数组等。也许使用valgrind或类似的。

答案 2 :(得分:1)

很抱歉对此线程进行了解决,但在调试类似问题时,我终于找到了一个尚未列在此处的可能答案,我相信这会对其他人遇到这类问题有所帮助。

答案(在我的情况下)是,仍然安装了部分代码,但是我们的构建系统无法确保测试实际上会链接到新编译的版本。相反,加载了动态库,它们期望与调用它们的代码不同的vtable布局。

当然,可能的症状是执行错误的函数,或者对虚函数的调用因分段错误而失败。这实际上取决于vtable布局如何在两个版本之间发生变化。

如果这是您的问题背后的原因,make uninstall应该修复它。

答案 3 :(得分:0)

你向我们展示的几乎没有任何东西是令人震惊的; - )

当我对内存损坏一无所知时,我习惯于启用实用程序gflags。在它们引发不合逻辑的噩梦之前,这是一个非常明智的应用程序,可以检测到许多犯罪事件。然而,事情变得非常缓慢。

尝试了解gflags尖叫的大多数步骤。

答案 4 :(得分:0)

这几乎总是陈旧的对象。清理或尝试在链接器路径中找到过时的目标文件。