我正在尝试做:
try{
int * i = NULL;
*i = 3;
}catch(Exception &Err){
ShowMessage(Err.Message);
}
我虽然这应该捕获访问冲突异常并通过显示错误消息来处理它。
但由于某种原因,我变得简单
访问冲突
消息而不是完整的
模块 YYY 中的访问违规 XXX。写入地址 ZZZ。
顺便说一句,ExceptObject()由于某种奇怪的原因,例程返回 NULL。
我在这里想念什么?
我正在尝试做:
try{
int * i = NULL;
*i = 3;
}catch(Exception &Err){
ShowMessage(Err.Message);
}
我虽然这应该捕获访问冲突异常并通过显示错误消息来处理它。
但由于某种原因,我变得简单
访问冲突
消息而不是完整的
模块 YYY 中的访问违规 XXX。写入地址 ZZZ。
顺便说一句,ExceptObject()由于某种奇怪的原因,例程返回 NULL。
我在这里想念什么?
在 BCB5 中,捕获 EAccessViolation 有效,例如:
#define AV_TRY { try {
#define AV_CATCH } catch(EAccessViolation &av) {Application->MessageBox((("Access Violation caught: " + string(__FILE__) + "; " + string(__FUNC__) + "; " + IntToString(__LINE__) + "\n\n") + av.Message.c_str()).c_str(), ("Program Error in " + string(class_name.c_str())).c_str(), MB_OK);} }
请注意,class_name 是特定于该项目的,可能应该被 AnsiString(this->ClassName) 替换或省略。此外,我已将此代码从静默记录到数据库切换为显示 MessageBox。我只是将我在 AV_TRY ... AV_CATCH 中观察到 AV 的代码包装起来。
请参阅有关混合 SEH 和 C++ 异常的 MSDN 博客条目。这是两种不同类型的异常。试图将操作系统生成的结构化异常作为 C++ 异常捕获并不是开箱即用的正确方法。用这篇关于不这样做的帖子来缓和这一点。
捕获访问冲突可能是一个不错的目标——但您可能只想在调试的上下文中执行此操作。在生产代码中捕获访问冲突(或其他主要异常)并尝试处理它们很少会导致正确的操作。
标准 C++ 没有指定取消引用 NULL 指针会引发异常 - 它说它会导致未定义的行为。在 Windows 平台上,Windows 结构化异常处理使水有些混乱。这与 C++ 异常处理无关,只是某些 C++ 运行时可能会将这些异常转换为 C++ 异常。但是,依赖于这种翻译的代码是不可移植的。
try {
int * i = NULL;
*i = 3;
}
catch (...) {
// This would catch the access violation but you don't have any more
// information of what has gone wrong
}
但是,您可以使用结构化异常处理 (SEH) 来捕获所有 C++ 异常。由于 C++ 异常只是基于 SEH 的基于类的实现。