2011-08-08 134 views
3

我正在使用Poco C++庫並導致奇怪的問題。 Poco使用自己的共享指針類SharedPtr進行內部指針操作。在我的情況下,靜態對象Poco::SSLManager擁有SharedPtr證書處理程序對象的成員。當程序運行結束時,靜態對象被刪除,我發現分段錯誤。 使用GDB調試器我看到核心轉儲並不明白問題。在刪除SharedPtr對象(簡單操作:delete pObj)時發生Seg故障,但對象具有有效地址,例如 - 0x8fcbed8C++刪除有效地址的指針

爲什麼刪除指向有效地址的指針會導致分段錯誤?
可能是因爲對象在應用程序中創建應用程序副本並破壞主要?

+0

在刪除檢查空指針的對象指針之前以及刪除操作設置爲空之後。 – Reddy

+1

SharedPtr通常具有'ptr-> Release()'函數。檢查一下 – Gasim

+5

@Reddy:在調用'delete'之前不要檢查'null',因爲它被定義爲對'null'指針不做任何事情。 – Puppy

回答

11

有效地址只是一個可訪問的地址。這並不意味着刪除是正確的。你只能只有delete你從new得到什麼。如果你沒有new呢,你不能delete吧。刪除一個靜態或自動對象是未定義的行爲 - 以及從new以外的任何其他來源可能獲得的對象。

+5

此外,您只能刪除一次...... –

+3

此外,您絕對不應該刪除智能指針中出現的任何內容。智能指針被稱爲「智能」,因爲它們自己處理刪除操作。 –

+0

當然,新做了。但是在fork過程中做的新事情,以及靜態對象中的對象存儲(從共享庫創建 - 所以)在父進程中銷燬。我似乎可能是衝突。 – Reddy

0

您說的有關使用shared pointer的問題。如果該刪除是pObj上的最後一次刪除,則可能是該對象最後一次被刪除。所以共享指針指向的對象最終將被銷燬。在這種情況下,pObj的destructor被調用,也許你會從那裏得到Seg Fault。

另一方面,根據Poco lib使用的共享指針的實現方式,可能是您通過調用delete來濫用共享指針。

+0

Poco SharedPtr看起來像智能ptr並使用內部原子計數器。我還檢查了我的問題對象(InvalidCertificateHandler)的析構函數。這是簡單的對象,沒有父母,只有1個布爾變量。在析構函數中,我看到一些靜態對象SSLManager方法的調用,但是在註釋之後,它的應用程序行爲不會改變。 – Reddy

+0

我認爲你使用共享的ptr錯誤,但很難猜到。請修改您的帖子並添加一些代碼,例如您構建和操作[Shared Ptr]的行(http://www.appinf.com/docs/poco/Poco.RC.html#13607) –

0

正如其他人所說,這不是因爲你的指針看起來像「0x8fcbed8」那樣「好」,它是一個正確的指針。

實際上,如果你使用「刪除」,指針會保持它的值。但你不應該再用它了。 (最好在刪除後將其設置爲NULL,以便在調試器中顯示爲「空」)。

有一種工具可以幫助您查找在使用Linux進行開發時出現的問題。這是的valgrind

valgrind your_program [args] 

(只是你平時啓動命令前加上「Valgrind的」安裝的valgrind如果不是已經在這裏,必須爲它包在你的發行版,因爲它是一種廣泛使用的工具)

然後valgrind會在程序運行時檢查你的程序(放慢一點),並在你刪除不應該刪除的東西時馬上報告你。 (和很多其他錯誤)

0

這是非常困難的問題,我不明白問題充分,但我試圖解釋它和我的決議。 問題是平臺特定的,只發生在Gentoo linux上,gcc 4.5.5編譯器與Poco庫存在。

我有一個使用模塊(插件)處理不同請求的守護進程。模塊和守護進程使用一個使用poco庫的靜態庫。在靜態庫中有代碼來創建SSL連接,並作爲結果創建SSL管理器。靜態庫鏈接到模塊和deamon。

而在工作結束後,deamon我有分段故障,描述了我的問題。我將靜態庫更改爲共享庫並且問題消失了,沒有seg故障。一切正常。

真的,我不理解它,但似乎它是gentoo上的gcc編譯器錯誤。在其他Linux上與其他gcc所有的靜態庫工作良好。

+0

Gentoo Linux與gcc 4.5.5 - 錯誤4.4.5版本 – Reddy