首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >std::make_shared()在C++17中的变化

std::make_shared()在C++17中的变化
EN

Stack Overflow用户
提问于 2018-02-17 14:33:12
回答 2查看 4.4K关注 0票数 28

cppref中,以下内容一直保持到C++17:

如果在f(std::shared_ptr<int>(new int(42)), g())之后调用g并抛出异常,那么像new int(42)这样的代码可能会导致内存泄漏,而f(std::make_shared<int>(42), g())是安全的,因为两个函数调用从不交织。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-17 17:43:50

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()的副作用之后,甚至没有内存分配。

无论是哪种情况,无论如何都不会再次发生内存泄漏。

票数 20
EN

Stack Overflow用户

发布于 2018-02-17 14:43:58

P0145R3文件( 被接受转换为C++17)细化了几个C++构造的计算顺序,包括

后缀表达式从左到右计算。这包括函数调用和成员选择表达式。

具体而言,该文件在标准5.2.2/4段中增加了以下案文:

后缀表达式在表达式列表和任何默认参数中的每个表达式之前进行排序。与参数初始化相关的每一值计算和副作用以及初始化本身在每次值计算之前以及与任何后续参数的初始化相关的副作用之前进行排序。

票数 20
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48842397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档