是否可能存在内存泄漏以在堆上分配shared_ptr
Is there might be memory leak to allocate shared_ptr on the heap?
只需阅读此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
;它没有任何优势。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 使用RAII在给定次数的迭代后重新分配资源