2008-10-16 56 views
1

這可能是不可能的,但我想我會問...跟蹤自動變量生存期?

有沒有任何人可以想到的方式來跟蹤是否刪除了自動變量而不修改變量本身的類?例如,考慮這樣的代碼:

const char* pStringBuffer; 
{ 
    std::string sString("foo"); 
    pStringBuffer = sString.c_str(); 
} 

顯然,塊之後,pStringBuffer是懸空指針其可以是或可以不是有效的。我想要的是一種包含pStringBuffer(包含const char *的轉換運算符)的包裝類的方法,但聲明它所引用的變量仍然有效。通過改變引用變量的類型,我當然可以做到這一點(例如boost shared_ptr/weak_ptr),但我希望能夠在不對引用類型施加限制的情況下做到這一點。

的幾點思考:

  • 我可能需要更改分配語法包括
  • 我也許可以看看堆棧指針來檢測,如果引用的變量(這是罰款)我包裝類被分配的「晚於」被引用的類,但這看起來很拙劣而不標準(C++沒有定義堆棧行爲)。它可以工作,但。

想法/輝煌的解決方案?你可能會發現有用

回答

0

一種方法是更換new/delete運營商自己的實現,其標誌使用的內存頁釋放時(由operator new分配)爲不可訪問(由operator delete釋放)。您需要確保內存頁面不會被重新使用,但是由於內存耗盡,運行時間長度會有限制。

如果您的應用程序在取消分配後訪問內存頁(如上例所示),操作系統將捕獲嘗試訪問並引發錯誤。它本身並不完全跟蹤,因爲應用程序將立即停止,但它確實提供反饋:-)

此技術適用於狹窄場景,並且不會捕獲所有類型的內存濫用,但它可能很有用。希望有所幫助。

1

一般來說,在C++中是不可能的,因爲指針太「原始」了。此外,看看你是否被分配的時間晚於被引用的類將不起作用,因爲如果你改變了字符串,那麼c_str指針可能會改變。

在這種特殊情況下,您可以檢查字符串是否仍然爲c_str返回相同的值。如果是這樣,你可能仍然有效,如果它不是,那麼你有一個無效的指針。作爲一個調試工具,我會建議使用先進的內存跟蹤系統,比如valgrind(僅適用於linux,恐怕類似的程序存在windows,但我相信它們都是花錢的,這個程序是唯一的原因我的Mac上安裝了Linux)。代價是執行速度慢得多,valgrind會檢測你是否從無效指針讀取數據。雖然它並不完美,但我發現它檢測到許多錯誤,尤其是這種類型的錯誤。

+0

是的; Purify會做類似的事情,當它真正起作用時,不會在運行時損壞應用程序。不幸的是,它是一個運行時應用程序,需要花錢,並且在任何應用程序接近商業複雜性時都無法使用。 = / – Nick 2008-10-16 23:39:56

0

你可以在你提到的簡單情況下創建一個包裝類。也許是這樣的:

X<const char*> pStringBuffer; 
{ 
    std::string sString("foo"); 
    Trick trick(pStringBuffer).set(sString.c_str()); 
} // trick goes out of scope; its destructor marks pStringBuffer as invalid 

但它並不能幫助更復雜的情況:

X<const char*> pStringBuffer; 
{ 
    std::string sString("foo"); 
    { 
     Trick trick(pStringBuffer).set(sString.c_str()); 
    } // trick goes out of scope; its destructor marks pStringBuffer as invalid 
} 

這裏,失效發生的太快了。大多數情況下,您應該只編寫儘可能安全的代碼(請參閱:智能指針),但不要求更安全(請參閱:性能,低級別接口),並使用工具(valgrind,Purify)確保不會出現任何錯誤通過裂縫。

0

鑑於「pStringBuffer」是您的示例在sString超出範圍之後存在的唯一部分,您需要對其進行一些更改或替代,以反映此情況。一個簡單的機制是一種範圍守護,範圍匹配sString,當它被銷燬時影響pStringBuffer。例如,它可以將pStringBuffer設置爲NULL。

要做到這一點不改變類的「變量」只能在這麼多的方式來完成:

  • 介紹在相同的範圍內sString明顯變化(減少冗長,你可能會考慮一個宏來產生兩件事情)。不太好。

  • 用模板換行ala X sString:這是否是「修改變量的類型」是有爭議的......另一種觀點是sString成爲同一個變量的包裝。它也受到這樣的影響,你可以做的最好的是將模板化的構造函數傳遞參數傳遞給包裝的構造函數,直到有限的N個參數。

這些都沒有什麼幫助,因爲他們依賴開發人員記住使用它們。

一個更好的方法是使 「爲const char * pStringBuffer」 簡單 「的std :: string some_meaningful_name」,並分配給它的必要。鑑於參考計數,99.99%的時間不是太貴。