2012-01-23 122 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()的調用開始失敗。