谁能解释一下为什么这个异常没有被捕获?
try {
// This will cause an exception
char *p = 0;
char x = 0;
*p = x;
}
catch (...) {
int a = 0;
}
当我运行程序时,它在行*p = x处终止,我希望catch块会导致忽略此异常。
我正在使用Qt Creator(2.2)和Qt 4.7.2在Windows 7 32位的Visual studio 2008上编译。
这里没有抛出c++异常。您正在导致未定义行为,因为*p = x
取消了一个指针的空指针值。
异常只在您或您调用的代码执行throw
表达式时传播。未定义行为通常不支持catch
结构化异常处理__try和__catch将捕获系统错误,参见:
http://msdn.microsoft.com/en-us/library/swezty51 (v = vs.80) . aspx
解除NULL指针的引用是未定义的行为。通常,这将触发处理器陷阱和操作系统级错误。这可能会被映射到一个信号,比如SIGSEGV
,或者一个访问冲突错误,或者它可能会中止你的程序,或者做任何其他事情。
在Windows上,它被映射为一个"结构化异常",这与c++异常是不同的。根据您如何配置MSVC,您可能能够使用catch(...)
捕获此问题,但并非总是如此。
如果你想这样做,你需要写一个指针测试:
template<typename T>
inline T* ptr_test(T* test)
{
if (test == NULL)
{ throw std::runtime_error("Null Exceception");
}
return test;
}
那么你的代码看起来像这样:
try
{
// This will cause an exception
char* p = 0;
char x = 0;
*ptr_test(p) = x; // This is what java does.
// Fortunately C++ assumes you are smart enough to use pointers correctly.
// Thus I do not need to pay for this test.
//
// But if you want to pay for the test please feel free.
}
catch (...)
{
int a = 0;
}
您需要使用/EHa
编译器选项来打开(特定于Microsoft编译器)功能,该功能将启用SEH(结构化异常处理)异常(这是您的空访问触发器)可被catch(...)
捕获。
话虽如此,我不建议使用/EHa
。最好直接使用__try/__except
扩展或SEH API,并将"结构化"异常的处理与c++异常的处理分开。为什么?因为c++异常只是另一种完全合法的定义良好的控制流机制,但大多数触发SEH异常的事情可能表明您的软件已经进入未定义行为的领域,真正明智的做法是优雅地退出。使用/EHa会导致这种重要的区别变得不必要地模糊。
它没有被捕获,因为它不是一个异常-没有抛出任何东西。您正在访问空/未分配内存,这会导致分割错误,这是操作系统本身的信号。
信号只能被信号处理程序捕获,异常对你没有帮助。
异常只有在可能调用throw()的地方才有真正的帮助,比如当您使用提供给它的参数导致除零时,库会抛出异常。
你现在所做的就是解引用一个空指针,这不是一个异常。
如果你想让这段代码捕获一些东西,你必须先抛出一些东西。比如:
try {
// This will cause an exception
char *p = 0;
char x = 0;
if (p == 0) throw 1;
*p = x;
}
catch (...) {
int a = 0;
}
显然,上面示例中的catch
块将始终被执行。