2012-01-23 123 views
2

我有下面的类层次结构:段错误调用函数

ICSL::ISystemModel 
ICSL::ISystemModelAffine : public ISystemModel 
ICSL::Quadrotor::SystemModelQuadrotor : public QObject, ISystemModelAffine 
ICSL::Quadrotor::SystemModelQuadrotorSimulated : public public SystemModelQuadrotor 

然后,在另一个类我定义

SystemModelQuadrotor mDynamicModelReal; 
SystemModelQuadrotorSimulated mDynamicModelSimulated; 

在初始化我打电话了一堆的函数来设置两个变量mDynamicModelRealmDynamicModelSimulated没有问题。稍后,我从ISystemModel调用一些函数来访问一些变量,它们适用于mDynamicModelReal,但段错误为mDynamicModelSimulated。在gdb中检查,变量值是正确的,它似乎知道函数是什么,但它试图调用实际函数(基于我对这些东西的有限理解)抱怨。下面是GDB探测它segfaulted用于调用mDynamicModelSimulated.getName()

(gdb) print mDynamicModelSimulated.mName 
$19 = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x810658 "quadGaui5"}} 
(gdb) print mDynamicModelSimulated.getName 
$20 = {const std::string (ICSL::ISystemModel * const)} 0x44f506 <ICSL::ISystemModel::getName()> 
(gdb) print mDynamicModelSimulated.getName() 
Cannot access memory at address 0x4082c00000000030 

后,这里是的getName()的

Class ISystemModel { 
public: 
... 
virtual std::string const getName(){return mName;}; 
... 
protected: 
... 
std::string mName; 
... 
}; 

我不明白为什么它不能使该函数调用的定义。我确实发现,如果从函数定义中删除“virtual”,它不会出现段错误,但我不明白为什么会有所作为。我应该在哪里寻找问题的根源?

+0

你如何在父类中设置变量mName? – Izza

+0

您是否也在其他派生类中定义了'getName()'? – iammilind

+0

ISystemModel和ISystemModelAffine不会设置mName,而其他两个类只是在其构造函数中明确设置它(例如mName =“”;) getName()没有在其他地方定义(对于这些类) – ryan0270

回答

1

确保在堆上分配了任何QObject而不是堆栈。他们对这个筹码不太好。

0

我想你是从构造函数调用不允许的虚函数,并可能导致意外的行为。你可以检查它:)。

+0

不,我已经看透了,我没有在构造函数中调用任何虚函数。 – ryan0270

0

一种可能性是你的虚拟表正在被破坏(堆/栈溢出或不正确的指针解引用,如果甚至可能的话),所以虚拟调用getName()失败。将其更改为非虚拟时,它会成功,因为它不会触及虚拟表。尝试对该对象进行其他虚拟调用以查看是否有其他任何操作无效。

如果是腐败,那么它可能发生在这一点之前的任何时候。通过添加日志记录或跟踪并查看getName()的调用开始失败。