删除无效地址时C++引发异常



我正在制作一个自定义分配器,我知道应用程序何时尝试释放无效地址,但我不知道我应该抛出什么异常。例如:

...
int *a=new int;
delete a;
delete a;
...

当第二次删除发生时,我知道我的内存池中没有分配该地址,我需要抛出一个异常,让用户知道在程序中的某个时候他试图释放一个无效地址。

不允许operator delete抛出任何异常。从operator delete引发异常会导致未定义的行为。请参阅 [basic.stc.dynamic.deallocation]/3。

即使可以通过这种方式诊断双重删除,使用两次delete a;仍会导致未定义的行为。这是不可避免的,例如,因为delete a;也首先调用析构函数,并且通常不允许对对象调用析构函数两次。

即便如此,在不干预分配的情况下在同一指针上调用operator delete两次仍然会导致未定义的行为,因为第一次operator delete调用会结束已分配内存的存储持续时间,使指针值无效,并且将无效的指针值传递给任何释放函数会导致未定义的行为,请参阅 [basic.stc]/4。

当用户尝试双重删除指针时,您唯一能做的就是中止程序,例如通过调用std::abort。这可能是最好的做法,因为已经发生了未定义的行为,因此继续该程序将毫无意义,甚至存在安全风险。

我认为无效地址或无效删除没有内置异常,因为此错误本身不支持异常。

您可以设置自己的例外 - 非常简单 - 例如:

从这里复制的代码

#include <iostream>
#include <exception>
struct MyException : public std::exception
{
const char * what () const throw ()
{
return "C++ Exception";
}
}
int main()
{
try
{
throw MyException();
}
catch (MyException& e)
{
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
}
catch (std::exception& e)
{
// Other errors
}
}

注意:在使用这个之前,请参阅 Walnut 关于异常处理的评论。