【问题标题】:Is there might be memory leak to allocate shared_ptr on the heap?在堆上分配 shared_ptr 是否可能存在内存泄漏?
【发布时间】:2013-12-02 18:52:21
【问题描述】:

阅读这篇 SO 帖子 stdshared-ptr-exception-safety

所以下面的代码不会有内存泄漏:

std::shared_ptr<int> p3 (new int);

但是跟随一个怎么样:

func(new std::shared_ptr<int>(new int));

如果shared_ptr 的分配抛出bad_alloc 异常并且'new int' 已经被评估,我假设int 被泄露。 他们是否标准定义了new std::shared_ptr 需要首先分配内存然后评估参数new int

【问题讨论】:

  • 每次你说new 并且没有立即在智能指针的构造函数中,你就有潜在的内存泄漏。只是不要说new
  • 没错,小心new
  • Kerrek 所说的。另外,你到底为什么要动态分配std::shared_ptr
  • @Angew,我只是想弥补一下。这不是一个真实的例子。
  • 一个更可行但仍然适用的例子是func(std::shared_ptr&lt;int&gt;(new int), std::shared_ptr&lt;int&gt;(new int));

标签: c++ memory-leaks heap-memory shared-ptr


【解决方案1】:

是的,这是潜在的内存泄漏。

但是,std::shared_ptr 的用法非常不合常规。通常shared_ptr 保存在自动存储中(在堆栈上)以利用 RAII。

【讨论】:

    【解决方案2】:

    可能导致内存泄漏并且不安全。分配的std::shared_ptr 本身应该在某处受到保护。 shared_ptr 可能会抛出异常,您应该处理它。 new std::shared_ptr 也可以抛出异常,你也应该处理它。第一个异常不会导致内存泄漏,但第二个剂量。

    另一方面,您不需要动态分配std::shared_ptr;它没有任何优点。

    【讨论】:

      【解决方案3】:

      是的,它可能会泄漏。

      如果new std::shared_ptr抛出,则没有什么可以清理new int分配的内存。

      一般来说,自动delete 调用仅在构造函数在相应的new 之后引发时才会进行。

      详细来说,可以重写代码如下:

      // if 'new' throws, we just get a bad_alloc, nothing leaked
      int *iptr = new int;
      
      // if 'new' throws, nothing will clean up iptr
      //
      // if, for whatever reason, ctor of std::shared_ptr<int> throws,
      // its memory gets reclaimed by an implicit delete, but iptr's target
      // is still lost.
      auto *ptrptr = new std::shared_ptr<int>(iptr);
      
      // EDIT: If the constructor of shared_ptr fails, it will delete
      // the memory it is given, though this still doesn't eliminate the
      // leak that can occur if the above `new` fails.
      

      编辑:

      上面的例子和这个解释实际上是为了表明std::shared_ptr 与任何其他智能指针实现相比没有什么特别之处,或者某种接受指针作为构造函数参数的类型.

      在后一种情况下,它实际上取决于类型的构造函数对其参数的作用。在std::shared_ptr 的情况下,它很可能不会抛出异常,除非它未能分配控制块(如果是这样的话,实际上它是如何实现的)。

      如果std::shared_ptr 的构造函数确实失败了,至少在我使用的实现(VS2012)中,它实际上确实删除了它给定的内存。

      【讨论】:

        【解决方案4】:

        如果shared_ptr的分配抛出bad_alloc异常并且new int已经被评估,我假设int被泄露。

        是的,如果评估按此顺序进行,并且共享指针的分配失败,那么整数将被泄露。

        他们是否标准定义了new std::shared_ptr 需要首先分配内存然后评估参数new int

        不,它们是不确定的,如 C++11 5.3.4/16 中所述。

        所以智能指针的动态分配是危险的,不仅仅是奇怪和混乱。不要这样做。

        【讨论】:

          猜你喜欢
          • 2014-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-26
          • 2012-09-27
          • 2011-01-29
          • 2011-05-08
          相关资源
          最近更新 更多