2011-10-05 26 views
8

我有一個代碼,我使用指針訪問某些數據塊。在一些罕見的情況下,數據塊的一些成員是空的,結果指​​針變得懸空。實際上,我得到了正確的指針,但是當試圖用指針做某事時,程序崩潰了。有什麼辦法檢查指針是否懸空?

通常的建議是避免使用這種類型。但令人遺憾的是,我使用的框架要求我使用這種類型的數據訪問方法。

有沒有一種方法可以在對其進行任何操作之前「檢查」指針是否無效?顯然,檢查指針是否不等於NULL不起作用。我也試過這個:

try 
{ 
    CString csClassName = typeid(*pMyPointer).name(); // Check error condition 
    // The line below fails due to dangling pointer (data block is not valid). 
    hr = pMyPointer->MyPointerMethod(); 
} 
catch(bad_typeid) 
{ 
    return E_FAIL; 
} 
catch(...) 
{ 
    return E_FAIL; 
} 

這是正確的方法嗎?

回答

5

無法檢查原始指針是否有效。無效的指針不保證在訪問它們時失敗。您不需要使用原始指針,而需要使用某種形式的智能指針。

+0

我的指針應該是靜態的類..它仍然很好如果我使用智能指針? – Nikhil

+0

這完全沒有問題。您需要注意線程安全問題,但這對於智能指針與原始指針來說沒有什麼不同。 –

+2

我不認爲這很重要。唯一令我困擾的是,你的框架本身是否可以讓你的指針在沒有任何預先通知的情況下懸擺。請參閱,您必須從智能指針中提取原始指針並將其傳遞到您的框架。如果它保證指針在調用後仍然有效,或者如果它會變得無效就會被通知 - 很好,請繼續。 – Septagram

7

我認爲你正在看錯方向。你可能有一個錯誤,你無法正確初始化指針,太早刪除對象,並試圖在指針被刪除或重複之後重用它。如果是這樣的話,你應該專注於確定發生的原因並修復bug,而不是試圖找到隱藏bug的方法。

至於您使用typeid運算符的方法,答案是它是無效的。對於不包含虛函數的類型的對象,基於指針的靜態類型,在編譯時解析運算符。對於至少包含一個虛函數的對象,它在運行時被解析,但用無效指針調用typeid(p)是未定義的行爲,並且與看起來工作的方式相同,它可能會崩潰。

使用已經提出的智能指針可能取決於庫實際做了什麼以及是否可以隨時傳遞智能指針。一般來說,使用智能指針進行內存管理是一個不錯的主意,而這又會保證指針將被正確初始化(如果問題是初始化,則修復),並且由於您不再手動操作,因此如果問題出現與早期刪除不會再發生。但請注意,儘管這可能會解決問題,但我仍然認爲您需要了解指針在應用程序中無效的原因,因爲這可能是更大問題的徵兆。現在

,對如何檢查指針是否懸空或不是原來的問題,你不能做到這一點的程序,但你可以運行內部內存調試(你的程序的valgrind在Linux中,淨化或一組人的在Linux中),並且該工具將能夠幫助您確定指針是否從未初始化,或者如果在錯誤使用之前將內存釋放到系統中。

+0

感謝您的詳細解釋。我可以理解,我應該找到一個解決方案,而不是隱藏bug ...但是在設計的框架中有一個漏洞,我不能在短時間內改變。所以我正在尋找解決方法。我也嘗試過智能指針,但它沒有成功。 – Nikhil

1

你不需要智能指針。它們只是解決這個問題的一種可能的方法。

您可以使用相互引用:在引用對象(referencee)中,引用列表返回引用它的對象(引用者)。當需要釋放引用者時,首先遍歷引用列表並設置它們用來指向引用者的任何屬性爲null(通常你會想知道這是哪個屬性),然後釋放參考文獻。

相關問題