2010-04-29 186 views
2

這兩個代碼示例編譯和運行沒有問題。 使用第二個變體會導致內存泄漏。任何想法爲什麼? 在此先感謝您的幫助。內存泄漏使用shared_ptr

變體1:

typedef boost::shared_ptr<ParameterTabelle> SpParameterTabelle; 

struct ParTabSpalteData 
{ 
     ParTabSpalteData(const SpParameterTabelle& tabelle, const string& id) 
      :Tabelle(tabelle), Id(id) 
     { 

     } 

     const SpParameterTabelle& Tabelle; 
     string Id; 
}; 

變2:

struct ParTabSpalteData 
{ 
     ParTabSpalteData(const SpParameterTabelle& tabelle, const string& id) 
      :Id(id) 
     { 
      // causes memory leak 
      Tabelle2 = tabelle; 
     } 

     SpParameterTabelle Tabelle2; 
     string Id; 
}; 
+3

你是怎麼確定有泄漏的? – 2010-04-29 09:10:32

+0

@Hassan:我的IDE(Visual Studio 2008)有一個內存泄漏檢測,顯示程序退出後控制檯中泄漏的內存區域的地址。如果我使用變體,則泄漏控制檯輸出消失。 – nabulke 2010-04-29 09:19:17

回答

3

你檢查,你沒有循環共享指針引用?

例如:

class A { 
    public: shared_ptr<A> x; 
}; 

shared_ptr<A> a1(new A()); 
shared_ptr<A> a2(new A()); 
a1->x = a2; 
a2->x = a1; 

這裏A1和A2將永遠不會被釋放,因爲他們有指向對方這使他們活着。

所以在你的情況下,檢查SpParameterTabelle是否有ParTabSpalteData的參考,或者如果有另一種可能性獲得循環參考。  

+0

我在想這可能是這樣一個問題。但我認爲示例1應該表現出相同的行爲否?或者它會不會因爲它是一個引用而不是shared_ptr本身? – 2010-04-29 09:22:23

+0

是的,我檢查,無法找到任何週期。 我以爲也許在變種2的構造函數中const shared_ptr&to一個shared_ptr的賦值引發了這個問題,但找不到解釋... – nabulke 2010-04-29 09:24:00

+1

通過在指針上使用const&,shared_ptr不會增加它的使用次數。如果您像情況2那樣發行副本,它就會發生。所以有可能是一個循環... – Danvil 2010-04-29 09:26:03

0

請注意,傳遞智能指針作爲常量SpParameterTabelle &表不禁止您更改指針對象。

您是否嘗試過直接通過智能指針,作爲

struct ParTabSpalteData 
{ 
     ParTabSpalteData(SpParameterTabelle tabelle, const string& id) 
      :Tabelle2(tabelle), Id(id) 
     { 
     } 

     SpParameterTabelle Tabelle2; 
     string Id; 
}; 
0

輸出東西ParameterTabelle(跟蹤/ FILEOUT)的析構函數,或者設置一個斷點。它真的不會被調用兩次嗎?

我最近升級了一個VS2005項目到VS2010,突然VS2010報告了boost :: lexical_cast中的內存泄漏。而不是所有這些,只在一行上的一個模塊中 - 甚至還有其他類型相同的其他lexical_cast /其他類型的文件。

即使本地內存狀態的測試報告這是內存泄漏(僅適用於調試模式下的代碼):

void run_stream_tests(std::ofstream& out) 
{ 
#ifdef _DEBUG 
    CMemoryState preState; 
    preState.Checkpoint(); 
#endif 
    { 
    ...your code... 
    } 
#ifdef _DEBUG 
    CMemoryState postState; 
    postState.Checkpoint(); 
    CMemoryState diffState; 
    if(diffState.Difference(preState, postState)) 
    { 
    TRACE("Memory leaked!\n"); 
    preState.DumpAllObjectsSince(); 
    } 
#endif 
} 

所以,這也可能是一個VS2010/VS2008的問題。

+0

感謝您的輸入。考慮到這一點,我將使用Boundschecker或Purify來獲得關於內存泄漏的第二意見。 – nabulke 2010-04-29 12:29:06