C++使用try,catch在VS2015中捕获异常

本文介绍如何在Visual Studio 2015中处理C++代码产生的SEH异常,通过设置编译选项/EHa来捕获并处理非法内存访问等异常情况。

下面的代码:

#include "stdafx.h"
#include <iostream>

int main()
{
	try
	{
		char* pch;
		pch = (char*)00001234;   //给予一个非法地址 
		*pch = 6; //对非法地址赋值,会造成Access Violation 异常 
		std::cout << "It is OK !" << std::endl;
	}
	catch(...)
	{
		std::cerr << "catched" << std::endl;
	}

	getchar();

    return 0;
}

在VS2015 C++项目中会产生异常如下:

Debug调试模式:

8a03acaca697506ea0dd09102837f8b1534.jpg

Release模式:

8cd6e70d08cbde454bd71cdcb8541283af1.jpg

很明显这个异常并没有被处理!因为默认的VS2015编译器并不处理SEH异常。SEH是结构化异常处理的简称,当在编译选项中使用/EHa时,可包括 C/C++的结构化异常和系统生成或应用程序生成的异步异常,例如内存保护被零除浮点冲突等。MSDN关于try, catch的使用说明

a82ff557458f313284c1c03d1d9bbae7f73.jpg

设置EHa后重新编译,再次运行,就可以捕获到SEH异常了:

9fffe13d58f4c275d73995574f50dbf204a.jpg

捕获到异常,点击continue=>

45c0e3701d9ce116aacd03569d6ae814135.jpg

不调试直接运行发现已经能捕获到SEH异常了!

 

转载于:https://my.oschina.net/u/3489228/blog/1833306

C++使用 `try-catch` 捕获多个异常时,如果未能成功捕获异常,通常是由于以下几个原因导致的: ### 1. 异常类型不匹配 C++异常捕获机制依赖于异常类型的匹配。如果 `catch` 块中指定的异常类型与实际抛出的异常类型不匹配,该 `catch` 块将不会被捕获到。例如,如果抛出的是一个 `std::runtime_error` 对象,而 `catch` 块试图捕获 `int` 类型的异常,则不会匹配[^3]。 **解决方法:** 确保 `catch` 块中的异常类型与抛出的异常类型一致。可以使用多态捕获,即通过基类指针或引用捕获派生类异常。例如,`catch (const std::exception& e)` 可以捕获所有从 `std::exception` 派生的异常[^1]。 ### 2. `catch` 块顺序不当 C++捕获异常时会按照 `catch` 块的顺序进行匹配。一旦找到匹配的 `catch` 块,后续的 `catch` 块将不会被考虑。因此,如果更通用的 `catch` 块(例如捕获 `std::exception`)出现在更具体的 `catch` 块之前,可能会导致后者永远不会被执行[^3]。 **解决方法:** 将更具体的 `catch` 块放在更通用的 `catch` 块之前。例如: ```cpp try { // 可能抛出异常的代码 } catch (const std::runtime_error& e) { // 处理 runtime_error 异常 } catch (const std::exception& e) { // 处理其他标准异常 } ``` ### 3. 异常未被抛出或抛出方式错误 如果异常没有被正确地抛出,或者抛出的方式不正确(例如抛出的是一个局部变量的地址),可能会导致 `catch` 坕无法捕获异常。此外,如果在 `try` 块外部抛出了异常,那么该异常也不会被 `catch` 块捕获[^1]。 **解决方法:** 确保异常是在 `try` 块内部通过 `throw` 语句正确抛出,并且抛出的对象具有适当的生命周期。例如: ```cpp try { throw std::runtime_error("An error occurred"); } catch (const std::exception& e) { // 正确捕获异常 } ``` ### 4. 编译器优化或异常处理机制限制 某些编译器可能会对异常处理进行优化,或者在某些特定的编译选项下禁用异常处理。此外,C++异常处理机制本身也存在一定的限制,例如不能跨函数边界捕获异常(除非函数被包含在 `try` 块中)[^2]。 **解决方法:** 检查编译器文档,确保启用了异常处理支持(例如在 GCC 中使用 `-fexceptions` 选项)。同时,确保异常的抛出和捕获逻辑符合 C++ 的语言规范。 ### 5. 使用 `catch(...)` 捕获所有异常 如果希望捕获所有可能的异常,可以使用 `catch(...)` 语法。然而,这种方式无法获取异常的具体信息,因此通常用于最后的兜底处理。 **示例:** ```cpp try { // 可能抛出异常的代码 } catch (const std::runtime_error& e) { // 处理 runtime_error 异常 } catch (...) { // 捕获所有其他类型的异常 } ``` ### 总结 在 C++捕获多个异常时,需要确保异常类型匹配、`catch` 块顺序正确、异常在 `try` 块内正确抛出,并且编译器支持异常处理。通过合理设计 `catch` 块的顺序和类型,可以有效解决捕获多个异常时遇到的问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值