请阅读此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
?
答案 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
;它没有任何优势。