有些人可以解释一下为什么没有发现这个例外。
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 Studios 2008进行编译。
答案 0 :(得分:10)
这里没有抛出C ++异常。您正在导致未定义的行为,因为*p = x
使用空指针值解析指针。
只有当您或您调用的代码执行throw
表达式时,才会传播异常。 未定义的行为通常不会catch
能够使用。
答案 1 :(得分:3)
取消引用NULL指针是未定义的行为。通常,这将触发处理器陷阱和OS级错误。然后,这可能会映射到一个信号,例如SIGSEGV
,或者一个访问冲突错误,或者它可能会中止您的程序,或者执行其他任何操作。
在Windows上,它被映射到“结构化异常”,这是与C ++异常不同的野兽。根据您配置MSVC的方式,您可以使用catch(...)
来捕获此信息,但并非总是如此。
答案 2 :(得分:3)
如果您需要,您需要编写指针测试:
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;
}
答案 3 :(得分:2)
结构化异常处理__try和__catch将捕获系统错误,请参阅:
http://msdn.microsoft.com/en-us/library/swezty51(v=vs.80).aspx
答案 4 :(得分:1)
它没有被捕获,因为它不是一个例外 - 没有任何东西在扔。您正在访问空/未分配的内存,这会导致分段错误,这是来自操作系统本身的信号。
信号只能由信号处理程序捕获,例外情况不会对您有所帮助。
异常仅在某些内容可能会调用throw()的区域中提供帮助,就像当您使用您提供的参数导致零除零时抛出异常的库。
答案 5 :(得分:1)
你现在正在做的就是取消引用一个空指针,这不是一个例外。
如果你想让这段代码捕获一些东西,你必须先抛出一些东西。比如说:
try {
// This will cause an exception
char *p = 0;
char x = 0;
if (p == 0) throw 1;
*p = x;
}
catch (...) {
int a = 0;
}
显然,以上示例中的catch
块将始终执行。
答案 6 :(得分:1)
您需要使用/EHa
编译器选项来启用(Microsoft编译器specific)功能,该功能将启用SEH(Structured Exception Handling)异常(这是您的空访问触发的)可以通过catch(...)
进行追踪。
话虽如此,我不建议使用/EHa
。最好直接使用__try/__except
扩展名或SEH API,并将处理“结构化”异常与处理C ++异常分开。为什么?因为C ++异常只是另一种完全合法的定义良好的控制流机制,但是大多数触发SEH异常的事情都可能表明你的软件已经进入了未定义行为的领域,而且真正唯一明智的做法就是优雅地退出。使用/ EHa会导致这种重要的差异变得不必要地模糊。