【发布时间】:2018-01-21 03:07:46
【问题描述】:
我编写了下面的代码,它重载了new 和delete 运算符并在析构函数中抛出异常。
抛出异常时,为什么delete运算符中的代码没有执行(并打印“再见”)?
如果不应该执行,(如何)释放内存? one of the other delete operators 被调用了吗?重载其中一个会导致相应的代码被执行吗?或者内存根本没有被释放,因为失败的破坏意味着它不应该被释放?
#include <iostream>
using namespace std;
class A
{
public:
A() { }
~A() noexcept(false) { throw exception(); }
void* operator new (std::size_t count)
{
cout << "hi" << endl;
return ::operator new(count);
}
void operator delete (void* ptr)
{
cout << "bye" << endl;
return ::operator delete(ptr);
}
// using these (with corresponding new's) don't seem to work either
// void operator delete (void* ptr, const std::nothrow_t& tag);
// void operator delete (void* ptr, void* place);
};
int main()
{
A* a = new A();
try
{
delete a;
}
catch(...)
{
cout << "eek" << endl;
}
return 0;
}
输出:
hi
eek
我看了:
- throwing exceptions out of a destructor
- How does C++ free the memory when a constructor throws an exception and a custom new is used
- 及其他
但我无法找到关于 (1) 析构函数中的异常(与构造函数相反)和 (2) 重载删除究竟会发生什么的答案。
我不需要关于在析构函数中抛出异常是不好的做法的讲座 - 我只是遇到了类似的代码,我对这种行为很好奇。
如果存在此类参考,我希望得到标准或类似参考支持的答案。
【问题讨论】:
-
我已经写了下面的代码[...]我刚刚遇到了这个代码 ...我很困惑。
-
可能是为了简化他在 Internet 上找到的内容而编写的给定代码。
-
我确实使用 g++ 7.1.0 和 clang++ 3.8.0 得到了“再见”。不过,我找不到描述更改内容的 gcc 错误报告。
-
[expr.delete] 有“[注意:无论对象的析构函数或数组的某些元素是否抛出异常,都会调用释放函数。]”。 [except.ctor] 具有“对于任何存储持续时间的类类型的对象,其初始化或销毁被异常终止... [注意:如果对象是由 new-expression 分配的,调用匹配的释放函数(如果有)以释放对象占用的存储空间。]" 不过,我很难找到规范的措辞。
标签: c++ c++11 exception destructor delete-operator