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)。 这可能是什么问题?
我忘了提到有很多其他代码(可执行文件,库)
答案 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)
这几乎总是陈旧的对象。清理或尝试在链接器路径中找到过时的目标文件。