【发布时间】:2020-10-17 13:09:12
【问题描述】:
有效的现代 C++ 第 146 页:
void processWidget(std::shared_ptr<Widget> spw, int priority);
void cusDel(Widget *ptr);//a custom deleter
这是 C++17 之前的不安全调用:
processWidget(std::shared_ptr<Wdiget>(new Widget, cusDel), computePriority());
它曾经是不安全的,因为computePriority 可以在new Widget 之后但在std::share_ptr 构造函数之前调用,并且如果computePriority 产生异常,动态的allcoat Widget 将被泄露。
因此你可以这样做:
std::shared_ptr<Widget> spw(new Widget, cusDel);
processWidget(spw, computePriority());
现在这将在 shared_ptr 上添加一个复制构造函数操作。所以你也可以这样做:
std::shared_ptr<Widget> spw(new Widget, cusDel);
processWidget(std::move(spw), computePriority());
所以我的问题是,下面的代码是否仍然能够在 C++17 中泄漏内存?
processWidget(std::shared_ptr<Wdiget>(new Widget, cusDel), computePriority());
我读过this 和this 但我仍然不确定,我相信std::shared_ptr<Wdiget>(new Widget, cusDel) 和computePriority() 都在调用processWidget 之前排序,但是我认为computePriority() 仍然可以抛出一个在new 之后和shared_ptr 获得新创建对象的所有权之前的异常。
【问题讨论】:
-
好的,我的立场是正确的。顺便说一句,今天我对 C++ 的喜爱并没有增加。
-
@tevemadar 很遗憾听到这个消息。我希望您只会对一些 c++ 程序员有这种感觉。这种语言实际上很酷:)
-
@cigien 我没有说任何关于程序员使用 C++ 的事情,但那个例子是
int y = operator<<(S(j=1), j=2);。尽管括号有数学意义,也许还有常识,但最后似乎对j的不确定性感到有些自豪。这有点像8/2(2+2)模因,只是它变得真实。 -
@tevemadar 我不确定这是不是骄傲,这只是对语言提供的保证的认可。
-
@cigien 在您的评论之后我刚回来,然后重新阅读了这件事。我在这里评论错误的部分。我不关心
j的不确定性,这只是一个评估顺序,哪个参数(operator<<())排在第一位,我可以忍受“随机”。我关心S()的“随机”排序。如果j是一个全局变量,这种不确定的顺序性质可能意味着S()将1作为其参数,但看到j=2作为变量。其实那是我不喜欢的。
标签: c++ c++17 undefined-behavior exception-safety