【问题标题】:Memory leak using shared_ptr使用 shared_ptr 的内存泄漏
【发布时间】:2011-02-13 17:25:16
【问题描述】:

这两个代码示例都能顺利编译和运行。 使用第二种变体会导致内存泄漏。任何想法为什么? 提前感谢您的帮助。

变体 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;
};

【问题讨论】:

  • 您是如何确定有泄漏的?
  • @Hassan:我的 IDE (Visual Studio 2008) 具有内存泄漏检测功能,在程序退出后在控制台中显示泄漏内存区域的地址。如果我使用变体一,泄漏控制台输出就消失了。

标签: c++ shared-ptr


【解决方案1】:

您是否检查过,您没有循环共享指针引用?

例如:

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 有引用,或者是否还有其他可能获得循环引用。

【讨论】:

  • 我在想这可能是个问题。但我认为示例 1 应该表现出相同的行为,不是吗?还是不是因为它是引用而不是 shared_ptr 本身?
  • 是的,我检查过,但没有找到任何周期。我认为可能是在变体二的构造函数中将 const shared_ptr& 分配给 shared_ptr 导致了问题,但找不到解释......
  • 通过在指针上使用 const&,shared_ptr 不会增加其使用次数。如果您像案例 2 那样发布副本,它确实如此。所以某处可能有一个循环......
  • @nabulke 也许您应该尝试重新创建问题的最小实例以便我们可以编译它?
  • 经验法则我猜,获取智能指针的引用或指针正在颠覆智能指针的目的
【解决方案2】:

请注意,将智能指针作为 const SpParameterTabelle& tabelle 传递并不禁止您更改指针对象。

您是否尝试过直接传递智能指针,如

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

      SpParameterTabelle Tabelle2;
      string Id;
};

【讨论】:

    【解决方案3】:

    在 ParameterTabelle 的析构函数(trace/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 的问题。

    【讨论】:

    • 感谢您的意见。考虑到这一点,我将使用 Boundschecker 或 Purify 来获得有关内存泄漏的第二意见。
    【解决方案4】:

    Visual Studio 的内存泄漏检测也有可能是错误的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-22
      • 2011-10-04
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 2011-02-26
      相关资源
      最近更新 更多