2011-12-02 69 views
0

我有一個B類,它繼承了帶有一些虛函數的類A. B類也有一個虛擬函數(foo),似乎沒有地址。當我用調試器走時,它指出foo有0x00000000地址,當我嘗試加入時,它將在0x00000005處因訪問衝突而失敗。如果我讓這個函數不是虛擬的,調試器就會進入並且工作正常,直到我達到std::vector。在我撥打push_back時,它將在地址0x000000005處出現相同的訪問衝突,同時在地址0xabababab處寫入一些內容,並且調用堆棧指向插入函數中的互斥鎖。C++罕見的運行時錯誤

注意:我沒有使用任何其他線程,每次編譯時增量鏈接器都會崩潰。只有完整的鏈接器才能成功創建exe。編譯器來自Visual Studio 2008專業版,當解壓出未使用的源文件和源代碼時,就會出現此問題。

不幸的是,我無法恢復到以前的狀態,以便發現創建這個的變化。

如何在不恢復整個項目的情況下檢測問題的根源?也有人遇到這種錯誤,也許這可能是同一原因。

+7

給我們一些代碼。 –

+2

最可能的原因是您通過空指針調用成員函數。 – sharptooth

+0

我正在使用調試器,但它未能給我任何相關信息。指針不爲空,不幸的是我不能給你任何源代碼。 – Raxvan

回答

2

你猜虛擬表已經壞掉了,但這不太可能,因爲vtables通常存儲在只讀存儲器中。

我能想到的兩個原因針對此行爲:

  • 您正在使用的對象已被刪除。如果對象曾經是內存的話,它可能會偶然運行,但如果它被覆蓋,它會失敗。
  • 您使用的對象不是動態類型B.也許它是A型或可能是不相關的類型。

我已經成功地跟蹤這類問題與的printf調試:在B,析構函數,虛函數和失敗函數的構造與printf("XXX %p", this);添加了幾行,你就可以推斷髮生了什麼。

是的,我知道,的printf調試是不是很酷...

+0

感謝您的幫助:) – Raxvan

2

您正在調用空指針的虛函數。編譯器添加將在對象中使用隱藏指針的代碼來定位什麼是最終覆蓋,並且該操作失敗。當您將該函數更改爲非虛擬時,該調用將靜態分派,但同樣,由於this指針爲空,因此對成員的訪問將失敗。

您應該檢查您在代碼中調用方法的對象的有效性。

+0

該對象對非空指針有效 – Raxvan

+0

@Raxvan:嘗試在非虛擬版本內打印'(void *)this'並查看它打印出來的內容。 –

+0

發現錯誤,未創建類B。該指針應該保持類B,但它擁有一些其他類。 – Raxvan