【try……catch】C++ try…… catch 笔记(C语言中也可以Try-Catch异常处理)
目录
C++ try……catch
catch(CException *e) 打印异常信息
不经意间的内存泄露:try-catch(CException *e) [异常对象需要手动释放]
C++ try catch 捕获空指针异常,数组越界异常
C++ try catch 异常类
异常类大全
C try……catch
没用用到MFC,是不支持CException的。
C++ try……catch
catch(CException *e) 打印异常信息
在进行各种各样的操作的时候,有时会出现未知的错误,又不知道什么类型的,一时摸不着头脑了,以前写过捕获的代码,但是用到的时候忘记了,现在记下来:try{MoveFile("D:\\fd.txt", "C:\\dbdw\\b.txt"); //将D:\fd.txt移动到C:\dbdw并改名为b.txt(原来目录下文件不存在)}catch(CException *e)//&e{TCHAR szError[1024]; e->GetErrorMessage(szError,1024); // e.GetErrorMessage(szError,1024); ::AfxMessageBox(szError); }那么这样就可以知道什么错误了!
不经意间的内存泄露:try-catch(CException *e) [异常对象需要手动释放]
原本以为异常对象是不用手动释放的(即不用delete)但今天发现跑了N天的服务器程序内存使用增大在调试的时候也发现VS给出内存泄露的提示才知道CException自带Delete方法且需要手动调用像这样才对try
{}
catch (CException *e)
{e->Delete();
}在尽量保证代码健壮性的前提下再包上一层try-catch确实能够应对一些意外情况但所有基于CException的异常不能直接delete像下面的写法是错误的
try
{}
catch (CException *e)
{delete e;
}原文:https://blog.csdn.net/sidyhe/article/details/47400787
C++ try catch 捕获空指针异常,数组越界异常 (windows的 SEH)
SEH的全称是Structured Exception Handling,是Windows操作系统提供的一种异常处理方式。SEH是属于操作系统的特性,不为特定语言设计,从它的名字就能看出它是一种结构化的异常处理方式。SEH包括了2个部分:终止处理__try/__finally和异常处理__try/__except,下面分别进行介绍。
终止处理__try/__finally
__try/__finally可以保证无论try块内的代码执行结果如何,finally块内的代码总会被调用和执行。现在用下面的这个VC++中的控制台程序来说明。
int _tmain(int argc, _TCHAR* argv[]){__try{MessageBox(NULL, _T("Message from '__try' section"), _T("Test"), MB_OK);// 除零,人为的使程序崩溃//int i = 13;int j = 0;int m = i / j;}__finally{// 在这里添加处理程序崩溃情况的代码//// 这里以弹出一个对话框为例子//MessageBox(NULL, _T("Message from '__finally' section"), _T("Test"), MB_OK);}MessageBox(NULL, _T("Funcation completed"), _T("Test"), MB_OK);return 0;}
异常处理__try/__except
__try/__except是用来捕捉异常的,只有当try块中的代码出现异常的时候,except块中的代码才会被调用和执行。它的语法是这样的:
__try{// guarded code}__except(expression){// exception handler code}
它最大的一个好处就是可以完全控制异常进程。expression的值决定了异常被处理完后,进程该如何执行。下面依然用VC++中的控制台程序来说明。
int _tmain(int argc, _TCHAR* argv[]){__try{MessageBox(NULL, _T("Message from '__try' section"), _T("Test"), MB_OK);// 除零,人为的使程序崩溃//int i = 13;int j = 0;int m = i / j;}__except(EXCEPTION_EXECUTE_HANDLER){// 在这里添加处理程序崩溃情况的代码//// 这里以弹出一个对话框为例子//MessageBox(NULL, _T("Message from '__except' section"), _T("Test"), MB_OK);}MessageBox(NULL, _T("Funcation completed"), _T("Test"), MB_OK);return 0;}
更多见:《让程序在崩溃时体面的退出之SEH》https://blog.csdn.net/starlee/article/details/6636723
以下是原文来旧文,但是尝试了不行,应该是博主写错了,应该是SEH
void TestEmptyPointType()
{ try { int* p = NULL; *p = 3; } catch(...) { cout<< "非法地址操作异常" << endl; }
} void TestDivZeroType()
{ try { int b = 0; int a = 3/b; } catch(...) { cout<< "0除异常" << endl; }
} void TestMemoryOutType()
{ int * a = new int[4]; try { for (int i = 0; i<245; i++) { a++; } *a = 3; } catch(...) { cout<< "内存越界异常" << endl; }
}
C++ try catch 异常类
catch (CException *e) 的CException 就是一个类
主要
有
包括int、double(分别的)、exception(所有的)n等等类型。下面来超一段图表
异常类继承层级结构图如下:
每个类所在的头文件在图下方标识出来.
标准异常类的成员:
① 在上述继承体系中,每个类都有提供了构造函数、复制构造函数、和赋值操作符重载。
② logic_error类及其子类、runtime_error类及其子类,它们的构造函数是接受一个string类型的形式参数,用于异常信息的描述;
③ 所有的异常类都有一个what()方法,返回const char* 类型(C风格字符串)的值,描述异常信息。
标准异常类的具体描述:
原文:https://blog.csdn.net/songzi1111/article/details/9299587
异常类大全
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <fstream>
#include <memory>
#include <cstdlib>int main(int argc, char *argv[])
{try{throw std::range_error("Hello Wolrd");} catch (std::range_error e){std::cout << e.what() << std::endl;abort();} catch (std::underflow_error e){std::cout << e.what() << std::endl;abort();} catch (std::overflow_error e){std::cout << e.what() << std::endl;abort();} catch (std::length_error e){std::cout << e.what() << std::endl;abort();} catch (std::out_of_range e){std::cout << e.what() << std::endl;abort();} catch (std::invalid_argument e){std::cout << e.what() << std::endl;abort();} catch (std::domain_error e){std::cout << e.what() << std::endl;abort();} catch (std::runtime_error e){std::cout << e.what() << std::endl;abort();} catch (std::logic_error e){std::cout << e.what() << std::endl;abort();} catch (std::bad_cast e){std::cout << e.what() << std::endl;abort();} catch (std::bad_alloc e){std::cout << e.what() << std::endl;abort();} catch (std::exception e){std::cout << e.what() << std::endl;abort();}catch(...){std::cout<<"This fuck"<<std::endl;}return 0;
}
C try……catch
下午读了一篇名为《详解C的异常处理机制》的博文,才知道在C语言中,除了使用goto进行异常处理外,还可以使用setjmp和longjmp配合实现异常处理,而且比goto更加方便。如果利用C语言做一些宏定义,可以实现类似C++、Java等语言的try-catch结构。
博文《详解C的异常处理机制》链接地址
以下是根据该文介绍,写的关于try-catch的一些宏定义:
#ifndef __EXCEPION_H__
#define __EXCEPION_H__
#include
/// 异常标记
typedef struct tagExcepSign
{
jmp_buf _StackInfo; // 保存异常处理入口的堆栈信息
int _ExcepType; // 异常类型,0表示无异常,异常类型号一般取小于0的数
} ExcepSign;
/// 获取异常类型号
#define ExcepType(ExcepSign) ((ExcepSign)._ExcepType)
/// 可能抛出异常的代码块
#define Try(ExcepSign) if ( ((ExcepSign)._ExcepType = setjmp((ExcepSign)._StackInfo)) == 0 )
/// 捕获特定异常
#define Catch(ExcepSign, ExcepType) else if ((ExcepSign)._ExcepType == (ExcepType))
/// 捕获所有可能异常
#define CatchElse(ExcepSign) else if((ExcepSign)._ExcepType < 0)
/// 抛出异常
#define Throw(ExcepSign, ExcepType) longjmp((ExcepSign)._StackInfo, ExcepType)
#endif /* __EXCEPION_H__ */
下面的C代码使用了上述宏定义实现异常处理:
#include
#include "exception.h"
void ExceptionTest(int ExpType)
{
ExcepSign Ex;
// 异常类型号用负值表示
ExpType = ExpType > 0 ? -ExpType : ExpType;
Try(Ex) {
if (ExpType < 0) {
Throw(Ex, ExpType);
}
else {
printf("没有异常\n");
}
} Catch(Ex, -1) {
printf("异常类型:-1\n");
} Catch(Ex, -2) {
printf("异常类型:-2\n");
} CatchElse(Ex) {
printf("异常类型:未知(%d)\n", ExcepType(Ex));
}
}
void Test(void)
{
ExceptionTest(0); // 无异常
ExceptionTest(1); // 异常1
ExceptionTest(2); // 异常2
ExceptionTest(3); // 异常3
}
---------------------
原文:https://blog.csdn.net/yangping_zheng/article/details/20781071
Linux_C实现try catch异常捕获
前言:像如java这样的面相对象语言,异常处理机制让其代码更具健壮性,可以代码捕获到如算术异常,空指针异常等,俘获并能够在预知情况下进行相应处理。那么对于C而言,是否能实现其功能?简要分析:Linux有对线程或者进程退出时有一种信号量机制,而默认情况下,这种signal是系统自己处理的,而最统一的处理方式是exit,而至于什么原因退出这个完全取决于什么样的信号。至于linux下的这些signal多少,哪个对应什么情况自行查阅资料。Linux_c 的实现将通过宏来实现。直接粗暴上代码吧:
---------------------
原文:https://blog.csdn.net/jekenzhuang/article/details/79737147
exception.h
#ifndef EXCEPTION_H_#define EXCEPTION_H_#include <setjmp.h>#include <signal.h>/* MANPROCSIGnals. */#define MANPROCSIG_HUP 1 /* Hangup (POSIX). */#define MANPROCSIG_INT 2 /* Interrupt (ANSI). */#define MANPROCSIG_QUIT 3 /* Quit (POSIX). */#define MANPROCSIG_ILL 4 /* Illegal instruction (ANSI). */#define MANPROCSIG_TRAP 5 /* Trace trap (POSIX). */#define MANPROCSIG_ABRT 6 /* Abort (ANSI). */#define MANPROCSIG_IOT 6 /* IOT trap (4.2 BSD). */#define MANPROCSIG_BUS 7 /* BUS error (4.2 BSD). */#define MANPROCSIG_FPE 8 /* Floating-point exception (ANSI). */#define MANPROCSIG_KILL 9 /* Kill, unblockable (POSIX). */#define MANPROCSIG_USR1 10 /* User-defined MANPROCSIG_nal 1 (POSIX). */#define MANPROCSIG_SEGV 11 /* Segmentation violation (ANSI). */#define MANPROCSIG_USR2 12 /* User-defined MANPROCSIG_nal 2 (POSIX). */#define MANPROCSIG_PIPE 13 /* Broken pipe (POSIX). */#define MANPROCSIG_ALRM 14 /* Alarm clock (POSIX). */#define MANPROCSIG_TERM 15 /* Termination (ANSI). */#define MANPROCSIG_STKFLT 16 /* Stack fault. */#define MANPROCSIG_CLD MANPROCSIG_CHLD /* Same as MANPROCSIG_CHLD (System V). */#define MANPROCSIG_CHLD 17 /* Child status has changed (POSIX). */#define MANPROCSIG_CONT 18 /* Continue (POSIX). */#define MANPROCSIG_STOP 19 /* Stop, unblockable (POSIX). */#define MANPROCSIG_TSTP 20 /* Keyboard stop (POSIX). */#define MANPROCSIG_TTIN 21 /* Background read from tty (POSIX). */#define MANPROCSIG_TTOU 22 /* Background write to tty (POSIX). */#define MANPROCSIG_URG 23 /* Urgent condition on socket (4.2 BSD). */#define MANPROCSIG_XCPU 24 /* CPU limit exceeded (4.2 BSD). */#define MANPROCSIG_XFSZ 25 /* File size limit exceeded (4.2 BSD). */#define MANPROCSIG_VTALRM 26 /* Virtual alarm clock (4.2 BSD). */#define MANPROCSIG_PROF 27 /* Profiling alarm clock (4.2 BSD). */#define MANPROCSIG_WINCH 28 /* Window size change (4.3 BSD, Sun). */#define MANPROCSIG_POLL MANPROCSIG_IO /* Pollable event occurred (System V). */#define MANPROCSIG_IO 29 /* I/O now possible (4.2 BSD). */#define MANPROCSIG_PWR 30 /* Power failure restart (System V). */#define MANPROCSIG_SYS 31 /* Bad system call. */#define MANPROCSIG_UNUSED 31#define T Exception_ttypedef struct Exception_t{char *reason;}Exception_t;typedef struct Exception_frame{struct Exception_frame *prev;jmp_buf env;const char *file;int line;const T* exception;}Exception_frame;extern Exception_frame *Exception_stack;enum{EXCEPTION_ENTERED=0,EXCEPTION_RAISED,EXCEPTION_HANDLED,EXCEPTION_FINALIZED};/* Manage all process signal,and automanage signal by process cause exit directoryly,*/#define ManProcAllSig \int sum = 31; \while(sum){ \signal(sum,handle_proc_sig); \sum--; \}/*Throw a exception*/#define throw(e) exception_raise(&(e),__FILE__,__LINE__)#define rethrow exception_raise(exception_frame.exception, \exception_frame.file,exception_frame.line)void handle_proc_sig(int signo);void abort_without_exception(const Exception_t *e,const char *file,int line);void exception_raise(const T *e,const char *file,int line);#define try do{ \volatile int exception_flag; \Exception_frame exception_frame; \exception_frame.prev = Exception_stack; \Exception_stack = &exception_frame; \ManProcAllSig \exception_flag = setjmp(exception_frame.env); \if (exception_flag == EXCEPTION_ENTERED) \{#define catch(e) \if(exception_flag == EXCEPTION_ENTERED) \Exception_stack = Exception_stack->prev; \}else if(exception_flag == e){ \exception_flag = EXCEPTION_HANDLED;#define try_return \switch(Exception_stack = Exception_stack->prev,0) \default: return#define catch_else \if(exception_flag == EXCEPTION_ENTERED) \Exception_stack = Exception_stack->prev; \}else if(exception_flag != EXCEPTION_HANDLED){ \exception_flag = EXCEPTION_HANDLED;#define end_try \if(exception_flag == EXCEPTION_ENTERED) \Exception_stack = Exception_stack->prev; \} \if (exception_flag == EXCEPTION_RAISED) \exception_raise(exception_frame.exception, \exception_frame.file,exception_frame.line); \}while(0)#define finally \if(exception_flag == EXCEPTION_ENTERED) \Exception_stack = Exception_stack->prev; \}{ \if(exception_flag == EXCEPTION_ENTERED) \exception_flag = EXCEPTION_FINALIZED;#undef T#endif /* EXCEPTION_H_ */
exception.c
#include "exception.h"#include <stdio.h>#include <assert.h>Exception_frame *Exception_stack = NULL;void exception_raise(const Exception_t *e,const char *file,int line){Exception_frame *p = Exception_stack;assert(e);if(p == NULL){abort_without_exception(e,file,line);}p->exception = e;p->file = file;p->line = line;Exception_stack = Exception_stack->prev;longjmp(p->env,EXCEPTION_RAISED);}void abort_without_exception(const Exception_t *e,const char *file,int line){//fprintf(stderr,"Uncaught exception");if(e->reason)fprintf(stderr," %s",e->reason);elsefprintf(stderr,"at 0x%p",e);if(file && line > 0)fprintf(stderr, "raised at %s:%d\n",file,line);fprintf(stderr,"aborting...\n");fflush(stderr);abort();}void handle_proc_sig(int signo){if( signo == MANPROCSIG_HUP )printf(" Hangup (POSIX). \r\n");else if( signo == MANPROCSIG_INT )printf(" Interrupt (ANSI). \r\n");else if( signo == MANPROCSIG_QUIT )printf(" Quit (POSIX). \r\n");else if( signo == MANPROCSIG_ILL )printf(" Illegal instruction (ANSI). \r\n");else if( signo == MANPROCSIG_TRAP )printf(" Trace trap (POSIX). \r\n");else if( signo == MANPROCSIG_ABRT )printf(" Abort (ANSI). \r\n");else if( signo == MANPROCSIG_IOT )printf(" IOT trap (4.2 BSD). \r\n");else if( signo == MANPROCSIG_BUS )printf(" BUS error (4.2 BSD). \r\n");else if( signo == MANPROCSIG_FPE )printf(" Floating-point exception (ANSI). \r\n");else if( signo == MANPROCSIG_KILL )printf(" Kill, unblockable (POSIX). \r\n");else if( signo == MANPROCSIG_USR1 )printf(" User-defined signal if( signo == (POSIX). \r\n");else if( signo == MANPROCSIG_SEGV )printf(" Segmentation violation (ANSI). \r\n");else if( signo == MANPROCSIG_USR2 )printf(" User-defined signal 2 (POSIX). \r\n");else if( signo == MANPROCSIG_PIPE )printf(" Broken pipe (POSIX). \r\n");else if( signo == MANPROCSIG_ALRM )printf(" Alarm clock (POSIX). \r\n");else if( signo == MANPROCSIG_TERM )printf(" Termination (ANSI). \r\n");else if( signo == MANPROCSIG_STKFLT )printf(" Stack fault. \r\n");else if( signo == MANPROCSIG_CLD )printf(" Same as SIGCHLD (System V). \r\n");else if( signo == MANPROCSIG_CHLD )printf(" Child status has changed (POSIX). \r\n");else if( signo == MANPROCSIG_CONT )printf(" Continue (POSIX). \r\n");else if( signo == MANPROCSIG_STOP )printf(" Stop, unblockable (POSIX). \r\n");else if( signo == MANPROCSIG_TSTP )printf(" Keyboard stop (POSIX). \r\n");else if( signo == MANPROCSIG_TTIN )printf(" Background read from tty (POSIX). \r\n");else if( signo == MANPROCSIG_TTOU )printf(" Background write to tty (POSIX). \r\n");else if( signo == MANPROCSIG_URG )printf(" Urgent condition on socket (4.2 BSD). \r\n");else if( signo == MANPROCSIG_XCPU )printf(" CPU limit exceeded (4.2 BSD). \r\n");else if( signo == MANPROCSIG_XFSZ )printf(" File size limit exceeded (4.2 BSD). \r\n");else if( signo == MANPROCSIG_VTALRM )printf(" Virtual alarm clock (4.2 BSD). \r\n");else if( signo == MANPROCSIG_PROF )printf(" Profiling alarm clock (4.2 BSD). \r\n");else if( signo == MANPROCSIG_WINCH )printf(" Window size change (4.3 BSD, Sun). \r\n");else if( signo == MANPROCSIG_POLL )printf(" Pollable event occurred (System V). \r\n");else if( signo == MANPROCSIG_IO )printf(" I/O now possible (4.2 BSD). \r\n");else if( signo == MANPROCSIG_PWR )printf(" Power failure restart (System V). \r\n");else if( signo == MANPROCSIG_SYS)printf(" Bad system call. \r\n");else if( signo == MANPROCSIG_UNUSED)printf(" Unknow erroe. \r\n");Exception_frame *p = Exception_stack;Exception_stack = Exception_stack->prev;longjmp(p->env,signo);// exit(0);//exit process}
测试:test.c
#include <stdio.h>#include <signal.h>#include <stdlib.h>#include "exception.h"#include <unistd.h>void test1(){char* a = NULL;*a = 1;}void test2(){int num = 1;while(1){printf("number=%d\r\n",num++);sleep(1);}}int main(){try{test2();//Simulate NULL pointer exception!!}catch(MANPROCSIG_SEGV){ //Catch the exceptionprintf("NULL pointer !!\r\n");}catch_else{printf("Unknow Error!!\r\n");}finally{printf("DONE \r\n");}end_try;return 0;}
Linux 下 C++ 异常处理技巧
https://www.jianshu.com/p/4e14ba11fe78
【try……catch】C++ try…… catch 笔记(C语言中也可以Try-Catch异常处理)相关推荐
- IOS笔记-C语言中的指针与数组
1.指针与数组 1)指针与一维数组 i.数组指针(指向数组元素的指针) 类型 *指针变量名: 指针定义完成后要初始化(不想让指向任何内容,=0,=NULL) int a[10]; int *p = ...
- 《C语言深度剖析》学习笔记----C语言中的符号
本节主要讲C语言中的各种符号,包括注释符.单引号双信号以及逻辑运算符等. 一.注释符 注释符号和注释在程序的预编译期就已经被解决了,在预编译期间,编译器会将注释符号和注释符号之间的部分简单的替换成为空 ...
- C语言学习笔记---8C语言中的英文字符
在C语言中,单个字符的数据类型是char,长度是1字节,且只能容纳ASCII码表中的字符,也就是英文字符.字符类型由单引号' '包围,字符串由双引号" "包围. //正确的写法 c ...
- c语言中格式符号错误,C语言中符号格式说明
scanf 语法: #include int scanf( const char *format, ... ); scanf()函数根据由format(格式)指定的格式从stdin(标准输入)读取,并 ...
- 用r语言画出y = ax^2 + bx + c,R语言中如何使用最小二乘法
这里只是介绍下R语言中如何使用最小二乘法解决一次函数的线性回归问题. 代码如下: > x > y > lsfit(x,y) 结果如下: $coefficients Intercept ...
- c语言是pdd格式的文件吗,C语言中符号格式说明
scanf 语法: #include int scanf( const char *format, ... ); scanf()函数根据由format(格式)指定的格式从stdin(标准输入)读取,并 ...
- C语言中的优化技巧总结
1.选择合适的算法和数据结构 选择一种合适的数据结构很重要,如果在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多.数组与指针语句具有十分密切的关系,一般来说,指针比较灵活简洁,而数组 ...
- c语言中 加法符号如何定义,【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】...
第一题 #include int main() { unsigned int a=6; int b=-20; printf("%d\n",a+b); (a+b)>6? put ...
- java语言程序设计 笔记_Java语言程序设计笔记
本文主要向大家介绍了Java语言程序设计笔记,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 对象的自动清除 · 对象回收是由垃圾回收线程负责 · System.gc()方法可以要求系 ...
最新文章
- 神经网络“炼丹炉”内部构造长啥样?牛津大学博士小姐姐用论文解读
- String,StringBuffer与StringBuilder的区别??
- 在线流程图绘制网站draw.io支持的三种存储介质
- 属性名、变量名与 内部关键字 重名 加
- HTML使用vue的 event,vue-js 特殊变量$event常识
- React 18 RC 版本发布啦,生产环境用起来!
- Linux运维:现状、入门和未来之路
- java前期_【JAVA】前期环境配置
- java oracle数据库连接代码,java连接oracle数据库代码实例(注释详解)
- linux系统下 java 环境的安装
- Kaggle Future Sales“”竞赛 XGB_model_final
- RadAsm + OD 搭配编写和调试汇编程序
- SuperMap iDesktopX “电子地图坐标转换”—火星、百度坐标与常规坐标系之间的转换
- 将solidworks建的机器人模型导入到ros中
- 用wget命令从FTP服务器下载数据
- 【LaTeX】复杂表格的制作:Excel2LaTeX及细节调整
- 小技巧分享:Sourcetree 免登录注册破解教程
- 掌握计算机基础知识的必要性,浅谈高校开展面向学科门类的计算机基础课程的必要性...
- 32bit转64bit,使用anaconda实现python64位与32位共存【多次踩雷后的正确解决方法】
- 数字电路硬件设计系列(二)之DC-DC电源设计