C++用C++11分配shared_ptr(std::shared_ptl):将shared_ptr初始化为临时变量仍然
C++ allocating shared_ptr with C++11 (std::shared_ptr): Is it still bad to initialize the shared_ptr into a temporary variable?
我读到了这个答案,作者提到了boost最佳实践,其中写道:
避免使用未命名的shared_ptr临时存储来保存键入;看看原因这是危险的,考虑一下这个例子:
void f(shared_ptr<int>, int);
int g();
void ok() {
shared_ptr<int> p(new int(2));
f(p, g());
}
void bad() {
f(shared_ptr<int>(new int(2)), g());
}
函数ok严格遵循准则,而bad构造临时shared_ptr到位,承认内存泄漏的可能性。自从函数参数是按未指定的顺序计算的,这是可能的对于先计算new int(2),再计算g(),我们可能永远不会得到如果g抛出异常,则返回到sharedptr构造函数<gt;
上述异常安全问题也可以通过使用中定义的makeshared或allocate_shared工厂函数boost/make_shared.hp.这些工厂函数还提供通过合并拨款提高效率。
我想我会开始使用make_shared
,但我想知道这条建议是否仍然适用于C++11 shared_ptr
。我之所以这么问,是因为我真的不完全理解为什么抛出g()
会阻止ctor被调用。
是的,C++11的shared_ptr
也以同样的方式工作。
我之所以这么问,是因为我真的不完全理解为什么抛出g()会阻止调用ctor。
你不明白什么?这是一个操作顺序问题,标准不需要特定的顺序。让我们将语句解压为一系列表达式:
auto __temp = new int(2);
auto &&__temp2 = g();
auto __temp3 = shared_ptr<int>(__temp);
你现在看到问题了吗?如果g
抛出,那么__temp3
将永远不会被初始化。因此,__temp
将泄漏。
C++标准不要求以这种方式对语句进行解包。但它也没有禁止它。编译器可以自由地按自己认为合适的方式对这些独立表达式进行排序。
我认为C++11中的求值顺序没有任何变化。也就是说,除了只需要一个而不是两个内存分配之外,使用std::make_shared<T>(...)
在安全性方面是更好的选择。
关于什么问题:以下对f()
论点的评估是完全有效的:
$tmp = new int(1)
(使用$tmp
表示编译器提供的临时变量)g()
std::shared_ptr<int>($tmp)
现在,如果g()
抛出,则永远不会执行对其他部分的评估,即永远不会构造std::shared_ptr<int>
,并且$tmp
被泄漏。
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++中的指针否定 (!ptr == NULL)
- 从const ptr*转换为ptr*时出现问题
- 无法使用 libtool 将 -shared 参数传递给 g++
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- shared-ptr-C++shared_ptr与unique_ptr用于资源管理