VC++异常捕获__try...__except和try...catch的使用介绍(附源码)
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++异常捕获__try...__except和try...catch的使用介绍(附源码)相关的知识,希望对你有一定的参考价值。
VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585 在C/C++的代码中,为了防止代码块执行的过程中产生异常导致软件崩溃,我们会给代码块添加__try...__except或try...catch保护,防止软件因为操作内部触发的异常产生崩溃。本文简单地介绍一下这两种异常捕获的使用示例。
1、概述
当软件运行过程中代码抛出异常,如果异常没有处理,且异常不可自动恢复,会导致软件崩溃闪退。C/C++中提供了异常保护机制,可以捕获到异常并处理掉,这样软件不会因为一些操作的内部错误而产生崩溃,软件可以正常的运行下去。
C语言中提供了SEH结构化异常捕获__try...__except,C++中则在__try...__except基础上提供了C++版本的try...catch机制,使用try...catch可以捕获到代码抛出的多种类型的异常,比如捕获到抛出的异常类信息。
2、使用C版本的__try...__except捕获异常
C语言版本的__try...__except的声明如下:
__try
// guarded code
__except ( expression )
// exception handler code
我们在调用API函数htmlHelp打开.chm帮助文档时,如果指定路径中的.chm文件不存在(可能是路径不对,也可能是文件被删除了),HtmlHelp函数内部会抛出异常,软件会发生崩溃。后来我们直接添加__try...__except去捕获异常,对调用HtmlHelp的代码添加保护,保证即使.chm文件不存在,也不能让软件发生崩溃,相关代码如下:
bool OpenChmHelpFile( LPCTSTR lpStrPath )
HWND hHelpWnd = NULL;
__try
hHelpWnd = HtmlHelp( NULL, lpStrPath, HH_DISPLAY_TOPIC, NULL );
__except( EXCEPTION_EXECUTE_HANDLER )
hHelpWnd = NULL;
if ( NULL == hHelpWnd )
WriteLog( _T("[OpenChmHelpFile] HtmlHelp execute failed, path [%s]!"), lpStrPath );
return false;
return true;
在上述代码中,在__except分支条件中直接设置EXCEPTION_EXECUTE_HANDLER,表示此处我们认领并处理这个异常,这样就不会因为异常未得到处理导致软件崩溃了。
3、使用C++版本的try...catch捕获异常
C++版本的try...catch的声明如下:
try
// code that could throw an exception
[ catch (exception-declaration)
// code that executes when exception-declaration is thrown
// in the try block
[catch (exception-declaration)
// code that handles another exception type
] . . . ]
// The following syntax shows a throw expression:
throw [expression]
使用C++版本的try...catch去捕获异常,不仅能捕获到代码抛出的基本类型的异常,还能捕获到C++代码抛出的异常类。比如在进程内存不足时,我们去new一段内存时可能会返回失败,new内部会抛出异常,此时我们可以使用try...catch捕获到异常,并查看到产生异常的原因,相关代码如下:
#include <iostream>
using namespace std;
int main()
char *p;
int i = 0;
try
do
p = new char[10*1024*1024];
i++;
Sleep(5);
while(p);
catch(const std::exception& e)
std::cout << e.what() << "\\n"
<< "分配了" << i*10 << "M" << std::endl;
return 0;
new抛出的是std::exception异常类,该异常类的定义如下:
D:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\include\\vcruntime_exception.h
namespace std
#pragma warning(push)
#pragma warning(disable: 4577) // 'noexcept' used with no exception handling mode specified
class exception
public:
exception() noexcept
: _Data()
explicit exception(char const* const _Message) noexcept
: _Data()
__std_exception_data _InitData = _Message, true ;
__std_exception_copy(&_InitData, &_Data);
exception(char const* const _Message, int) noexcept
: _Data()
_Data._What = _Message;
exception(exception const& _Other) noexcept
: _Data()
__std_exception_copy(&_Other._Data, &_Data);
exception& operator=(exception const& _Other) noexcept
if (this == &_Other)
return *this;
__std_exception_destroy(&_Data);
__std_exception_copy(&_Other._Data, &_Data);
return *this;
virtual ~exception() noexcept
__std_exception_destroy(&_Data);
virtual char const* what() const
return _Data._What ? _Data._What : "Unknown exception";
private:
__std_exception_data _Data;
;
通过调用exception::What接口获取产生异常的原因。
以上是关于VC++异常捕获__try...__except和try...catch的使用介绍(附源码)的主要内容,如果未能解决你的问题,请参考以下文章
测试 __try, __finally, __except(被__finally捕获的异常, 还会被上一级的__except捕获。反之不行)