在一个表达式语句中最多使用一次 new
2.17 ID_multiAllocation
由于子表达式的求值顺序存在很多未声明的情况,在表达式中多次显式分配资源易造成资源泄漏。
示例:
fun(
shared_ptr<T>(new T),
shared_ptr<T>(new T) // Non-compliant, potential memory leak
);
例中 fun 函数的两个参数均包含 new 表达式,而参数的求值顺序在标准中是未声明的,出于优化等目的,可能会先为两个 T 类对象分配内存,之后再分别执行对象的构造函数,如果某个构造函数抛出异常,已分配的内存就无法回收了。
从 C++17 开始,参数的求值过程不再有所重叠,示例代码的问题在 C++17 后会有所缓解,但为了更广泛的适用性和兼容性,应避免在表达式中多次显式分配资源。
应改为:
shared_ptr<T> a{new T}; // Compliant
shared_ptr<T> b{new T}; // Compliant
fun(a, b);
这样即使构造函数抛出异常也会自动回收已分配的内存。
更好的方法是避免显式资源分配,用 make_shared、make_unique 等工厂函数代替 new 运算符:
fun(
make_shared<T>(),
make_shared<T>() // Compliant, safe and brief
);
相关
依据
ISO/IEC 14882:2003 5.2.2(8)-unspecified
ISO/IEC 14882:2011 5.2.2(8)
ISO/IEC 14882:2017 8.2.2(5)