2010-04-29 155 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