C ++ 17中的std :: make_shared()更改 [英] std::make_shared() change in C++17
问题描述
在 cppref 中,以下内容一直适用到C ++ 17:
In cppref, the following holds until C++17:
代码(例如
f(std::shared_ptr<int>(new int(42)), g())
)可能会导致 如果g
在new int(42)
之后被调用并引发 例外,而f(std::make_shared<int>(42), g())
是安全的,因为 两个函数调用永远不会交错.
code such as
f(std::shared_ptr<int>(new int(42)), g())
can cause a memory leak ifg
gets called afternew int(42)
and throws an exception, whilef(std::make_shared<int>(42), g())
is safe, since two function calls are never interleaved.
我想知道C ++ 17中引入的哪些更改使其不再适用.
I'm wondering which change introduced in C++17 renders this no longer applicable.
推荐答案
The evaluation order of function arguments are changed by P0400R0.
在进行更改之前,函数自变量的求值相对于彼此未排序.这意味着g()
的评估可能会插入std::shared_ptr<int>(new int(42))
的评估中,这会导致您引用的上下文中所述的情况.
Before the change, evaluation of function arguments are unsequenced relative to one another. This means evaluation of g()
may be inserted into the evaluation of std::shared_ptr<int>(new int(42))
, which causes the situation described in your quoted context.
更改后,函数参数的评估不确定地进行顺序排列,没有交织,这意味着std::shared_ptr<int>(new int(42))
的所有副作用都发生在g()
的副作用之前或之后.现在考虑g()
可能抛出的情况.
After the change, evaluation of function arguments are indeterminately sequenced with no interleaving, which means all side effects of std::shared_ptr<int>(new int(42))
take place either before or after those of g()
. Now consider the case where g()
may throw.
-
如果
std::shared_ptr<int>(new int(42))
的所有副作用都早于g()
的副作用,则分配的内存将由std::shared_ptr<int>
的析构函数释放.
If all side effects of
std::shared_ptr<int>(new int(42))
take place before those ofg()
, the memory allocated will be deallocated by the destructor ofstd::shared_ptr<int>
.
如果std::shared_ptr<int>(new int(42))
的所有副作用都发生在g()
的副作用之后,则甚至没有内存分配.
If all side effects of std::shared_ptr<int>(new int(42))
take place after those of g()
, there is even no memory allocation.
无论哪种情况,都不会再次发生内存泄漏.
In either case, there is no memory leak again anyway.
这篇关于C ++ 17中的std :: make_shared()更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!