空指针的C++异常

Fel*_*bek 5 c++ exception-handling nullpointerexception

我有一个小功能(在DLL中),看起来像这样:

int my_function(const char* const s)
{
    try {
        return my_object->do_something_with(s);
    } catch (exception& e) {
        return ERROR_CODE;
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为try-catch块可以防止内部可能发生的任何事情my_object传播到外部.不幸的是,我错了,我调用此函数的程序(来自VB)刚停止工作,因为我传递了一个空指针参数.

那么,为什么我的try-catch块不能像(I)那样工作呢?有解决方法吗?我以前在Java中编程很多,我认为它会在那里工作......

rli*_*bby 10

本来可以在Java中工作,因为在Java中NullPointerException已经有了.在C++中,没有这样普遍存在的异常,解除引用空指针只会产生分段错误.

此外,在C++中没有强制的异常类型层次结构.任何类型的例外都可能被抛出; 例外不必来自std::exception.(所以即使有人定义了一个class NullPointerException {};,但没有指定它来源std::exception,你仍然不会捕捉它.)

  • 是的,可以捕获使用`catch(...)`结构抛出的任何异常,但您可能不应该这样做.显然,使用此构造,您无法访问异常对象或甚至无法确定其类型,因此您可以使用它来正确处理异常,这是值得怀疑的.最后,在取消引用空指针时,这仍然无法使您从程序中避免出现分段错误. (2认同)

Ste*_*sop 5

在C++中取消引用空指针是未定义的行为.这意味着C++标准对可能发生的事情没有任何限制.任何事情都是允许的 - 特定的实现可能会记录自己的行为,或者可能不会.如果不是,则行为可能是一致且可预测的,或者可能不是.

通常,最好假设未定义的行为会导致计算机着火(或格式化硬盘).只是不要激怒它.当然,在你的代码的第一次切割中很难避免错误,因此当你意外地执行它并且你的计算机没有着火时,那么你很幸运,修复bug并继续前进.您的功能可以重写:

int my_function(const char* const s)
{
    if (s == 0) return ERROR_CODE;
    return my_object->do_something_with(s);
}
Run Code Online (Sandbox Code Playgroud)

或者,你可以修复调用者不首先传递空指针,或者你可以修复do_something_with接受空指针.带指针参数的C++函数应记录是否允许空指针.

不同的人会以(s==0)不同的方式编写测试- 它可能是(s==NULL)(NULL==s)(!s).选一个你喜欢的.

当然,在实践中,编译器有充分的理由不让您的计算机着火,现代操作系统会尝试确保行为不当的应用程序不会给其他应用程序造成太大的不便.因此,在大多数系统上,大多数情况下,当您取消引用空指针时,您将获得某种硬件异常或信号,或者您的进程将被终止,或者可能在嵌入式系统上,设备将锁定并需要重新启动.

你通常不会得到一个C++风格的软件异常,你可以用任何类型的catch子句捕获,虽然Windows确实有一个名为SEH的功能,你可以使用它来获得这种行为.