C++程序闪退原因定位

  1. 内部直接或者间接调用了terminate函数或者abort函数,terminate函数内部也是默认调用了abort函数。

C++异常处理之terminate函数

C++中处理异常的过程是这样的:在执行程序发生异常,可以不在本函数中处理,而是抛出一个错误信息,把它传递给上一级的函数来解决,上一级解决不了,再传给其上一级,由其上一级处理。如此逐级上传,直到最高一级还无法处理的话,运行系统会自动调用系统函数terminate,

学会使用terminate函数有助于异常处理

一 当一个异常产生的时候调用terminate函数,代码:

[cpp] view plaincopyprint?

  1. #include <iostream>   
  2. #include <exception>   
  3. using namespace std;  
  4. void on_terminate(){  
  5.  cout<<"terninate function called!"<<endl;  
  6.  cin.get();  
  7. }  
  8. int main(void){  
  9.  set_terminate(on_terminate);  
  10.  throw exception();  
  11.  cout<<"terminate function not called!"<<endl;  
  12.  cin.get();  
  13.  return 0;  
  14. }  

terminate被调用的情况:
1 当发送一个异常,并且构造函数产生异常
2 当发送一个异常,或者析构函数产生异常
3 一个静态对象的构造或者析构发送一个异常
4 以atexit注册的函数发生异常的时候
5 自定义一个异常,但是实际上没有异常产生的时候
6 调用缺省的unexcepted()函数时候
例子说话:
 

[cpp] view plaincopyprint?

  1. #include <iostream>   
  2. #include <exception>   
  3. using namespace std;  
  4. void on_terminate(){  
  5.  cout<<"terminate function called!"<<endl;  
  6.  cin.get();  
  7. }  
  8. class custom_exception{  
  9.  custom_exception(){  
  10.  }  
  11.  custom_exception(const custom_exception& excep){  
  12.   throw exception();  
  13.  }  
  14. };  
  15. void case_1(){  
  16.  try{  
  17.   throw custom_exception();  
  18.  }  
  19.  catch(...){  
  20.  }  
  21. }  

当一个函数抛出了一个throw异常的时候,如果该函数内部构造了对象的话,系统会先对该对象调用析构函数,当对象调用完了析构函数以后,才开始执行异常的抛出工作。
同时在具有继承关系的类的异常中,子类的异常应该放在前面,而基类的异常应该放到最后面,这样可以使子类的异常先获得处理,父类的异常最后处理。
 

[cpp] view plaincopyprint?

  1. #include<iostream>    
  2. using namespace std;   
  3. class X   
  4. {   
  5. public:   
  6.  class Trouble {};   //注意:类中嵌套类的申明和定义,学习!!!    
  7.   class small: public Trouble {};   
  8.   class big:public Trouble {};//类中的继承!!!    
  9.   void f(){   
  10.   throw big();   
  11.  }   
  12. };   
  13. int main()   
  14. {   
  15.   X x;   
  16.   try{   
  17.     x.f();   
  18.   }   
  19.   catch(X::Trouble &)   
  20.   {   
  21.     cout<<"caught Trouble"<<endl;   
  22.   }   
  23.   catch(X::small&)   
  24.   {   
  25.     cout<<"caught small"<<endl;  
  26.  }   
  27.   catch(X::big&)   
  28.   {   
  29.     cout<<"caught big"<<endl;   
  30.   }   
  31.    return 0;   
  32. }   

如果这样的话,抛出的big()类型异常则被trouble类垄断,应该倒着写才可以实现顺序捕获所有异常,另外使用...可以捕捉所有的异常,这个应该放到最后面才可以。
省略号异常处理器不允许接受任何参数,所以无法得到任何相关异常的信息,也无法知道异常的类型,这种catch语句经常用于清理资源并重新抛出所捕获的异常。

Terminate或者abort结束的程序 , 会在windows事件查看器上面反映出来

 

### Dev-C++ 调试模式下输入后程序闪退的解决方案 在使用 Dev-C++ 进行调试时,如果遇到程序输入后立即退出的情况,可以通过调整配置来解决问题。以下是详细的分析和解决方法: #### 配置 launch.json 文件 一种常见的解决方式是通过修改 `launch.json` 文件中的设置项,从而避免程序运行结束后自动关闭 CMD 窗口的行为。具体来说,在启用断点调试的情况下,可以尝试不更改默认文件中的 `program` 配置,而是直接在 `launch.json` 中添加或调整相关参数[^1]。 例如,可以在 `launch.json` 文件中加入如下配置: ```json { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/your_program.exe", // 替换为实际生成的可执行文件路径 "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": true, // 使用外部控制台防止窗口快速关闭 "MIMode": "gdb" } ] } ``` 上述配置的关键在于设置了 `"externalConsole": true` 参数,这会强制打开一个新的命令行窗口用于显示程序输出并等待用户手动关闭,有效解决了窗口瞬间消失的问题。 #### 修改编译选项 另一种可能的原因是由于编译器未正确处理标准输入流而导致的异常行为。在这种情况下,建议重新构建项目,并确认使用的编译器支持当前代码所需的特性。按照以下流程操作可以帮助定位问题所在: - 打开菜单栏中的 **Run** -> **Set Active Compiler...** - 选择合适的 GCC 编译器版本(推荐最新稳定版) - 接下来点击运行按钮或者按快捷键 F5 启动调试过程[^2] 完成以上步骤之后再次测试是否存在同样的崩溃现象;如果没有改善,则继续排查其他潜在因素比如依赖库加载失败等。 #### 关于 Libusb 的注意事项 对于涉及 USB 设备交互的应用场景而言,还需要特别注意所选用的第三方动态链接库是否兼容目标平台以及其初始化逻辑是否会引发非预期终止状况的发生。Libusb-win32 提供了一种无需深入研究驱动开发细节即可操控硬件资源的方法[^3] 。然而当集成此类功能模块至现有工程当中时务必遵循官方文档指导完成必要的前期准备工作以免遗漏重要环节进而影响最终效果呈现形式。 综上所述,针对 Dev-C++ 下调试期间发生的频繁闪退情况可以从多个角度切入寻找根本原因并对症施治直至恢复正常运作状态为止。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程经验随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值