Jan*_*dec 9 c++ memory-leaks exception-handling visual-c++ language-lawyer
动态分析在我们的代码库中发现了奇怪的内存泄漏.有问题的代码如下:
Something *p = new Something(getArgument());
Run Code Online (Sandbox Code Playgroud)
功能getArgument()
有时会抛出的地方.当它抛出时,新分配的对象被泄露.这是由Visual Studio 2015(MSC++ 19.0)编译的.
现在,当我检查规范(C++ 14最终草案)时,§5.3.4/ 8奇怪地说:
甲新表达 可以通过调用一个获得所述对象存储分配功能(3.7.4.1).如果 new-expression通过抛出异常终止,它可以通过调用释放函数来释放存储(3.7.4.2).如果分配的类型是非数组类型,则分配函数的名称为
operator new
,并且释放函数的名称为operator delete
.如果分配的类型是数组类型,则分配函数的名称为operator new[]
,并且释放函数的名称为operator delete[]
.
使用'may'(我上面突出显示)这意味着编译器可以自由地不这样做.
这是这样的:
注意:代码在表达式完成时会正确删除对象.这没有错误.问题严重在于new-expression抛出时会发生什么.
从最新的草案来看,相关引用位于:
\n\n\n\n\nexpr.new/8:新表达式 可以通过调用分配函数 ([basic.stc.dynamic.allocation]) 来获取对象的存储空间。如果 new 表达式因抛出异常而终止,则它可以通过调用释放函数来释放存储空间。....
\n
“可以”的使用优先于后续部分:
\n\n\n\n\nexpr.new/21如果上述对象初始化的任何部分因抛出异常而终止,并且可以找到合适的释放函数,则调用释放函数来释放该对象所在的内存。正在构造,之后异常继续在 new 表达式的上下文中传播。如果找不到明确\n 匹配的释放函数,则传播异常\n 不会导致对象的内存被释放。[\xe2\x80\x89注意:当被调用的分配函数不分配内存时,这是适当的;否则,很可能会导致内存泄漏。\xe2\x80\x94\xe2\x80\x89尾注\n \xe2\x80\x89]
\n
但是 C++14 及更早版本中新表达式的不确定排序给您带来了困扰;其中说:
\n\n\n\n\n$5.3.4/18 分配函数的调用相对于 new-initializer 中表达式的计算是不确定地排序的。\n 已分配对象的初始化在 new-expression 的值计算之前排序。如果分配函数返回空指针或使用异常退出,则未指定是否计算 new 初始化程序中的表达式。
\n
摘自 C++14 草案
\n\n根据本文的通过。现在我们在 C++17 中定义了一个序列:
\n\n\n\n\nexpr.new/19 \n 分配函数的调用在 new-initializer 中的表达式求值之前排序。分配的对象的初始化在 new 表达式的值计算之前进行排序。
\n
归档时间: |
|
查看次数: |
185 次 |
最近记录: |