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

时间:2013-11-19 09:33:59

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

请阅读此SO帖子stdshared-ptr-exception-safety

因此下面的代码不会有内存泄漏:

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

但是如何跟随一个:

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

如果评估了shared_ptr throw bad_alloc异常和'new int'的分配,我认为int会被泄露。 他们是否标准定义new std::shared_ptr需要先分配内存然后评估参数new int

4 个答案:

答案 0 :(得分:3)

是的,这可能是内存泄漏。

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

答案 1 :(得分:2)

是的,它可以泄漏。

如果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)中,它实际上 删除它给出的内存。

答案 2 :(得分:2)

  

如果已经评估了shared_ptr抛出bad_alloc例外和new int的分配,我认为int会被泄露。

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

  

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

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

因此智能指针的动态分配是危险的,而不仅仅是奇怪和令人困惑。不要这样做。

答案 3 :(得分:0)

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

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