捕获访问冲突exception?

int *ptr; *ptr = 1000; 

可以使用标准C ++来捕获内存访问冲突exception,而不使用任何特定于Microsoft的内容。

不。 当你做不好的事情时,C ++不会抛出一个exception,这会导致性能下降。 诸如访问违规或被零错误划分等事情更像是“机器”exception,而不是语言层面的事情。

读它,哭!

我想到了。 如果不从处理程序中抛出,处理程序将会继续,exception也会继续。

当你抛出你自己的exception并处理它时,魔法就会发生。

 #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <tchar.h> void SignalHandler(int signal) { printf("Signal %d",signal); throw "!Access Violation!"; } int main() { typedef void (*SignalHandlerPointer)(int); SignalHandlerPointer previousHandler; previousHandler = signal(SIGSEGV , SignalHandler); try{ *(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place. } catch(char *e) { printf("Exception Caught: %s\n",e); } printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n"); printf("But please kids, DONT TRY THIS AT HOME ;)\n"); } 

Visual Studio中使用try – > catch(…)块来捕获任何types的exception(除以零,访问冲突等)是非常简单的方法。 一个小项目设置调整就足够了。 只需在项目设置中启用/ EHa选项。 请参阅项目属性 – > C / C ++ – >代码生成 – >将启用C ++exception修改为“是有SEHexception” 。 而已!

在此处查看详细信息: http : //msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx

这种情况是依赖于实现的,因此需要供应商特定的机制来进行陷阱。 与微软这将涉及SEH,* nix将涉及一个信号

一般来说,虽然捕获访问冲突exception是一个非常糟糕的主意。 几乎没有办法从AVexception中恢复,试图这样做只会导致难以发现程序中的错误。

如上所述,在Windows平台上没有非微软/编译器厂商的方式来做到这一点。 但是,捕获正常的try {catch(exception ex){}方法中的这些exceptiontypes对于错误报告来说显然是有用的,并且更适当地退出您的应用程序(正如JaredPar所说的,应用程序现在可能有麻烦了) 。 我们在一个简单的类包装器中使用_se_translator_function,它允许我们在一个try处理程序中捕获以下exception:

 DECLARE_EXCEPTION_CLASS(datatype_misalignment) DECLARE_EXCEPTION_CLASS(breakpoint) DECLARE_EXCEPTION_CLASS(single_step) DECLARE_EXCEPTION_CLASS(array_bounds_exceeded) DECLARE_EXCEPTION_CLASS(flt_denormal_operand) DECLARE_EXCEPTION_CLASS(flt_divide_by_zero) DECLARE_EXCEPTION_CLASS(flt_inexact_result) DECLARE_EXCEPTION_CLASS(flt_invalid_operation) DECLARE_EXCEPTION_CLASS(flt_overflow) DECLARE_EXCEPTION_CLASS(flt_stack_check) DECLARE_EXCEPTION_CLASS(flt_underflow) DECLARE_EXCEPTION_CLASS(int_divide_by_zero) DECLARE_EXCEPTION_CLASS(int_overflow) DECLARE_EXCEPTION_CLASS(priv_instruction) DECLARE_EXCEPTION_CLASS(in_page_error) DECLARE_EXCEPTION_CLASS(illegal_instruction) DECLARE_EXCEPTION_CLASS(noncontinuable_exception) DECLARE_EXCEPTION_CLASS(stack_overflow) DECLARE_EXCEPTION_CLASS(invalid_disposition) DECLARE_EXCEPTION_CLASS(guard_page) DECLARE_EXCEPTION_CLASS(invalid_handle) DECLARE_EXCEPTION_CLASS(microsoft_cpp) 

原来的类来自这个非常有用的文章:

http://www.codeproject.com/KB/cpp/exception.aspx

不是exception处理机制,但是可以使用由C提供的signal()机制。

 > man signal 11 SIGSEGV create core image segmentation violation 

写入一个NULL指针可能会导致一个SIGSEGV信号

至less对于我来说,在另一个答案中提到的signal(SIGSEGV ...)方法在Win32和Visual C ++ 2015上不起作用 。 为我工作的是使用_set_se_translator() 。 它是这样工作的:

步骤1 )确保在项目属性/ C ++ /代码生成/启用C ++exception中启用了SEHexception(/ EHa) ,如Volodymyr Frytskyy的回答中所述。

步骤2 )调用_set_se_translator() ,为新的exception转换器传入一个函数指针(或lambda)。 它被称为翻译器,因为它基本上只是采取低级别的exception,并重新抛出它更容易捕捉,如std::exception

 // Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation; _set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) { std::string error = "SE Exception: "; switch (u) { case 0xC0000005: error += "Access Violation"; break; default: char result[11]; sprintf_s(result, 11, "0x%08X", u); error += result; }; throw std::exception(error.c_str()); }); 

步骤3 )像通常那样捕获exception:

 try{ MakeAnException(); } catch(std::exception ex){ HandleIt(); }; 

这样的违规意味着代码有严重问题,而且不可靠。 我可以看到,一个程序可能想要以一种希望不会覆盖以前的数据的方式来保存用户的数据,希望用户的数据还没有被破坏,但是根据定义,没有标准的方法处理未定义的行为。