2011-03-28 55 views
0

我正在調試一個奇怪的問題,其中一個對象VMT突然間似乎指向了基礎對象的方法。C++調試「氣味」

class Base 
{ 
    virtual void foo() {} 
} 

class Derived: public Base 
{ 
    void foo() {} 
} 

Derived * d = new Derived; 

... much complex fettling ... 

d->foo(); // Help! called Base::foo()!!! 

原來,在「複雜」代碼中的錯誤是切實做好delete d;。除了說boost::noncopyable是你的朋友,並且從未在任何情況下推出你自己的智能指針類之外,我不會詳細討論。

但是,我的問題是 - VMT的這種改變是一種很好的「氣味」,你正在處理一個被刪除的對象?我猜VMT在銷燬期間會被「展開」回到Base

顯然,這是可怕的implmentation依賴,而我是「幸運」的是,內存沒有被踐踏......

回答

4

不知道問題是什麼 - 但我要說,這:

我是「幸運」的是,內存沒有被踐踏......

是錯誤的:你不是幸運的 - 你是幸運。如果在刪除過程中內存被踐踏,你可能會讓代碼更接近實際問題,錯誤會更加清晰。

失敗的代碼應該儘早失敗,以便提供有關失敗位置的提示。

+0

+1我喜歡你的「幸運」版本比我的更好。 – 2011-03-28 11:40:11

+0

同意。我很樂意'delete'將指針自動設置爲NULL。 – Roddy 2011-03-28 11:40:36

+1

@Roddy不幸的是,這將是有限的使用,因爲可能有其他指針指向同一個對象。理想情況下,所有這些都將設置爲空,但這當然需要跟蹤所有指針,而C++由於性能原因而不會執行這些指針。 – 2011-03-28 11:47:17

0

你很幸運,你得到了基類行爲而不是段錯誤。

如果您正在使用已刪除的對象,行爲未定義。

1

我只能說g ++,因爲你觀察到的vtable變更實際上是發生了什麼。您有時可以使用它來確定指針的對象被刪除,但這通常不會有很大幫助,因爲刪除可能發生在多個位置。 shared_ptrunique_ptr是你的朋友來管理內存。