c++ - C++17 中的 std::make_shared() 更改

标签 c++ language-lawyer c++17 make-shared exception-safety

cppref ,以下内容在 C++17 之前有效:

code such as f(std::shared_ptr<int>(new int(42)), g()) can cause a memory leak if g gets called after new int(42) and throws an exception, while f(std::make_shared<int>(42), g()) is safe, since two function calls are never interleaved.

我想知道 C++17 中引入的哪个更改使这不再适用。

最佳答案

函数参数的计算顺序由 P0400R0 更改.

在更改之前,函数参数的计算相对于彼此是无序的。这意味着评估 g()可以插入到std::shared_ptr<int>(new int(42)) 的评价中,这会导致您引用的上下文中描述的情况。

更改后,函数参数的计算顺序不确定,没有交错,这意味着 std::shared_ptr<int>(new int(42)) 的所有副作用发生在 g() 之前或之后.现在考虑 g() 的情况。可能会抛出。

  • 如果 std::shared_ptr<int>(new int(42)) 的所有副作用发生在 g() 之前,分配的内存将被std::shared_ptr<int>的析构函数释放.

  • 如果 std::shared_ptr<int>(new int(42)) 的所有副作用发生在 g() 之后,甚至没有内存分配。

在任何一种情况下,无论如何都不会再次发生内存泄漏。

关于c++ - C++17 中的 std::make_shared() 更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48842397/

相关文章:

c++ - 什么时候 glFlush 调用过于频繁?

c++ - C++ const mysqlpp::String模棱两可的错误

c++ - 在标准中使用 8.5.3p4,如何确定 T 与 T& 的引用兼容?

c++ - 带有 std::any 和 std::optional 的 any_cast

c++ - 复制初始化的默认模板参数推导

c++ - 如何在 C++ 中添加非常大的数字?

c++ - 使用多个返回值初始化多个成员

c++ - 什么标准条款强制执行这种左值到右值的转换?

c++ - 在 C++ 中使用不正确的向下转换访问基类成员

c++ - 当参数是参数包时,右值引用不起作用