C++17中哪个改动消除了std::shared_ptr构造的内存泄漏风险?
咱们先把问题的根源捋明白:在C++17之前,编译器对函数参数的求值顺序没有严格约束——它可以自由安排不同实参的执行时机,甚至允许交错执行实参内部的子表达式。放到你提到的代码里,就可能出现这种危险场景:
编译器先执行
new int(42)分配了内存,拿到裸指针,但还没来得及把这个指针传给std::shared_ptr的构造函数,就跑去调用g()了。如果这时候g()抛出异常,那这个裸指针就没人接管,已经分配的内存直接泄漏。
而C++17引入的函数实参求值顺序的严格化规则,彻底堵上了这个漏洞:
- C++17明确规定,函数的每个实参的求值(包括其内部所有子表达式的执行、副作用的完成)必须完全结束后,才能开始另一个实参的求值。
具体到你的例子,现在只会有两种安全的执行顺序:
- 先完整执行
std::shared_ptr<int>(new int(42)):从内存分配到智能指针构造完成,内存已经被shared_ptr接管,哪怕之后g()抛出异常,shared_ptr的析构函数也会自动释放内存。 - 先完整执行
g():如果g()抛出异常,那new int(42)根本不会执行,自然不存在内存泄漏的问题。
这下,哪怕不用std::make_shared,直接构造std::shared_ptr的写法也不会有内存泄漏风险了。
内容的提问来源于stack exchange,提问作者Lingxi
相关产品推荐
相关产品推荐

