C++ std::共享ptr异常安全

C++ std::共享ptr异常安全,c++,c++11,memory-leaks,shared-ptr,C++,C++11,Memory Leaks,Shared Ptr,我刚刚在阅读时意识到,带有单指针参数的std::shared_ptr的构造函数并不例外 因此,以下代码包含可能的内存泄漏: std::shared_ptr<int> p3 (new int); std::shared_ptr p3(新整数); 原因是可能发生两次分配: 调用构造函数之前的第一个 shared_ptr构造函数中的第二个(例如VS 2012中的情况) 这里有两个问题: 如果第二次分配引发异常,第一次分配的内存是否会泄漏? 如果答案是肯定的: 使用std::shar

我刚刚在阅读时意识到,带有单指针参数的
std::shared_ptr
的构造函数并不例外

因此,以下代码包含可能的内存泄漏:

std::shared_ptr<int> p3 (new int);
std::shared_ptr p3(新整数);
原因是可能发生两次分配:

  • 调用构造函数之前的第一个
  • shared_ptr构造函数中的第二个(例如VS 2012中的情况)
这里有两个问题:

如果第二次分配引发异常,第一次分配的内存是否会泄漏?

如果答案是肯定的:

使用std::shared\u ptr的正确习惯用法是什么?

  • 使用make_共享
  • 将第一次分配的所有权授予std::unique\u ptr,然后转移所有权
  • 还有别的想法吗
模板显式共享ptr(Y*p);
[util.smartptr.shared.const]/6在无法获取内存以外的资源时引发:
错误分配
,或实现定义的异常。
[util.smartptr.shared.const]/7异常安全:如果引发异常,则调用
delete p


所以不,没有内存泄漏。

迟回答,但最好使用
make_shared()
实现异常安全,如中所述:以下代码不是异常安全的:

 f( std::shared_ptr<T1>{ new T1 }, std::shared_ptr<T2>{ new T2 } );
f(std::shared_ptr{new T1},std::shared_ptr{new T2});
鉴于以下情况:

f( std::make_shared<T1>(), std::make_shared<T2>() );
f(std::make_shared(),std::make_shared());

哦,天哪,一个关于智能指针的有趣问题。我想这已经不可能了+1已经找到了这个问题的答案…而且,替换可能更有效。在某些情况下,您不能使用
make_shared
,即在继承的类型上调用new,而
shared_ptr
被模板化以保留基类型。对于参与方来说有点晚,但我在这里是为了另一个不可能的用例:当您需要指定自定义deallocator时。但是有一个简单的解决方法:永远不要在同一个语句中多次调用std::shared_ptr{}。另一种情况是,您可能不想使用std::make_shared():如果从使用std::make_shared()生成的共享_ptr中获得比共享_ptr寿命更长的弱_ptr,对象T占用的内存将持续存在,直到所有弱所有者也被销毁。(为什么?std::make_shared实际上比shared_ptr构造函数更有效,因为它只对对象T和控制块进行一次分配,而不是两次分配。弱的_ptr需要控制块,因此您只能使用这个整体块。)
f( std::make_shared<T1>(), std::make_shared<T2>() );