目录

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异常处理)相关推荐

  1. IOS笔记-C语言中的指针与数组

    1.指针与数组 1)指针与一维数组 i.数组指针(指向数组元素的指针) 类型  *指针变量名: 指针定义完成后要初始化(不想让指向任何内容,=0,=NULL) int a[10]; int *p =  ...

  2. 《C语言深度剖析》学习笔记----C语言中的符号

    本节主要讲C语言中的各种符号,包括注释符.单引号双信号以及逻辑运算符等. 一.注释符 注释符号和注释在程序的预编译期就已经被解决了,在预编译期间,编译器会将注释符号和注释符号之间的部分简单的替换成为空 ...

  3. C语言学习笔记---8C语言中的英文字符

    在C语言中,单个字符的数据类型是char,长度是1字节,且只能容纳ASCII码表中的字符,也就是英文字符.字符类型由单引号' '包围,字符串由双引号" "包围. //正确的写法 c ...

  4. c语言中格式符号错误,C语言中符号格式说明

    scanf 语法: #include int scanf( const char *format, ... ); scanf()函数根据由format(格式)指定的格式从stdin(标准输入)读取,并 ...

  5. 用r语言画出y = ax^2 + bx + c,R语言中如何使用最小二乘法

    这里只是介绍下R语言中如何使用最小二乘法解决一次函数的线性回归问题. 代码如下: > x > y > lsfit(x,y) 结果如下: $coefficients Intercept ...

  6. c语言是pdd格式的文件吗,C语言中符号格式说明

    scanf 语法: #include int scanf( const char *format, ... ); scanf()函数根据由format(格式)指定的格式从stdin(标准输入)读取,并 ...

  7. C语言中的优化技巧总结

    1.选择合适的算法和数据结构 选择一种合适的数据结构很重要,如果在一堆随机存放的数中使用了大量的插入和删除指令,那使用链表要快得多.数组与指针语句具有十分密切的关系,一般来说,指针比较灵活简洁,而数组 ...

  8. c语言中 加法符号如何定义,【 c语言中无符号和有符号的加法运算】【深入理解】--【sky原创】...

    第一题 #include int main() { unsigned int a=6; int b=-20; printf("%d\n",a+b); (a+b)>6? put ...

  9. java语言程序设计 笔记_Java语言程序设计笔记

    本文主要向大家介绍了Java语言程序设计笔记,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 对象的自动清除 · 对象回收是由垃圾回收线程负责 · System.gc()方法可以要求系 ...

最新文章

  1. 神经网络“炼丹炉”内部构造长啥样?牛津大学博士小姐姐用论文解读
  2. String,StringBuffer与StringBuilder的区别??
  3. 在线流程图绘制网站draw.io支持的三种存储介质
  4. 属性名、变量名与 内部关键字 重名 加
  5. HTML使用vue的 event,vue-js 特殊变量$event常识
  6. React 18 RC 版本发布啦,生产环境用起来!
  7. Linux运维:现状、入门和未来之路
  8. java前期_【JAVA】前期环境配置
  9. java oracle数据库连接代码,java连接oracle数据库代码实例(注释详解)
  10. linux系统下 java 环境的安装
  11. Kaggle Future Sales“”竞赛 XGB_model_final
  12. RadAsm + OD 搭配编写和调试汇编程序
  13. SuperMap iDesktopX “电子地图坐标转换”—火星、百度坐标与常规坐标系之间的转换
  14. 将solidworks建的机器人模型导入到ros中
  15. 用wget命令从FTP服务器下载数据
  16. 【LaTeX】复杂表格的制作:Excel2LaTeX及细节调整
  17. 小技巧分享:Sourcetree 免登录注册破解教程
  18. 掌握计算机基础知识的必要性,浅谈高校开展面向学科门类的计算机基础课程的必要性...
  19. 32bit转64bit,使用anaconda实现python64位与32位共存【多次踩雷后的正确解决方法】
  20. 数字电路硬件设计系列(二)之DC-DC电源设计

热门文章

  1. Python 网易邮箱简单发送邮件
  2. 10个免费开源的JS音乐播放器插件
  3. 成为优秀的高级开发员,重点在于……
  4. 速卖通产品如何推广引流?速卖通如何引流?
  5. 刘慈欣回应《三体》获奖nbsp;对…
  6. 函数式编程|python的函数式编程
  7. 4套主题bootstrap后台管理模板源码下载
  8. RabbitMq中的mandatory
  9. TMMi测试能力成熟度模型简介
  10. 爬虫需谨慎!那些你不知道的爬虫反爬虫套路,学起来!