是否可能存在内存泄漏以在堆上分配shared_ptr

Is there might be memory leak to allocate shared_ptr on the heap?

本文关键字:分配 shared ptr 存在 内存 泄漏 是否      更新时间:2023-10-16

只需阅读此SO post stdshared ptr异常安全

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

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

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

然而,这是std::shared_ptr的一种非常非常规的使用。通常,shared_ptr被保持在自动存储器中(在堆栈上)以利用RAII。

如果shared_ptr的分配引发bad_alloc异常,并且new int已经被评估,则我假设int被泄漏。

是的,如果按照这个顺序进行计算,并且共享指针的分配失败,那么整数就会泄漏。

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

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

因此,智能指针的动态分配是危险的,而不仅仅是怪异和混乱。不要这样做。

是的,它可能会泄漏。

如果new std::shared_ptr抛出,则没有任何东西可以清理new int分配的内存。

通常,只有当构造函数在相应的new之后抛出时,才会进行自动delete调用。

为了详细说明,您可以按如下方式重写代码:

// 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)中,它实际上确实删除了给定的内存。

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

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