C/C++ - 异常处理
目录
错误处理
异常处理
异常传播
异常规划
标准异常
自定异常
错误处理
-
在C语言中,错误通常通过函数的返回值来表示。
-
错误返回值
- 对于能返回特殊值(如NULL或负值)的函数,在调用时检查这些值来处理错误。
-
#include <stdio.h> #include <stdlib.h>#define DIV_RET_SUCCESS 1 #define DIV_RET_FAILED 0//C语言中通过函数返回值来判断执行成功与否 int myDiv(int num1, int num2, int* nRet) {if (num2 == 0){*nRet - 0;return DIV_RET_FAILED;}*nRet = num1 / num2;return DIV_RET_SUCCESS; }int main() {int ret = 0;if (myDiv(10, 2, &ret) == DIV_RET_SUCCESS){printf("%d \r\n", ret);}return 0; }
-
错误码全局变量
- 如 errno,这是一个全局变量,很多标准库函数在出错时会设置这个变量为相应的错误码。
-
#pragma warning(disable:4996) #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h>int main() {FILE* pFile = NULL;pFile = fopen("0xCC.txt", "r");if (pFile == NULL){printf("ErrorCode -> %d \r\n", errno);printf("ErrorMesg -> %s \r\n", strerror(errno));perror("fopen");}return 0; }
-
宏定义
- 通过宏定义可以创建简单的错误处理代码块,这个方法提供了一种快速插入常用错误处理程序代码的方式。
-
#include <stdio.h> #include <stdlib.h> #define HANDLE_ERROR(msg) \do { \perror(msg); \exit(EXIT_FAILURE); \} while(0) int main() {FILE *fp = fopen("file.txt", "r");if (!fp) {HANDLE_ERROR("Error opening file");}// 其余代码...fclose(fp);return 0; }
异常处理
-
throw:当问题发生时,程序会抛出一个异常。这是通过 throw 关键字完成的,后面跟着要抛出的异常对象。
throw ErrorCode throw "Erroe" -
try:try 块内的代码是可能产生异常的代码,当其中的代码抛出一个异常时,执行流会跳转到匹配的 catch 块。
-
catch:catch 块会捕获异常,并包含如何处理这些异常的代码。
try {//可能抛出异常的代码 } catch(ExceptionType var) //根据异常类型捕获 {//处理匹配异常类型 } catch(ExceptionType var) //根据异常类型捕获 {//处理匹配异常类型 }
-
示例代码
#include <iostream>int AllocMem() {//可能会抛出异常的代码放在try语句块内try{//throw 'A';long long* p = new long long[0xFFFFFFF];//thorw bad_allocation}catch (int exception){std::cout << exception << std::endl;}catch (char exception){std::cout << exception << std::endl;}catch (std::exception exception){std::cout << exception.what() << std::endl;}}int main() {AllocMem();return 0; }
异常传播
-
C++异常传播(Exception Propagation)是指在程序中如果一个函数内发生了异常,而该异常没有在该函数内得到处理,则该异常会被传递到函数调用者处,如果调用者也不处理,则继续传递,这样一直到最顶层调用者。如果最顶层调用者也没有处理异常,则程序可能崩溃。
- 如果try块内的代码抛出了异常,控制流会跳到第一个匹配的catch块。
- 如果在当前函数中没有匹配的catch块,异常会被传递给调用该函数的函数,并在那里寻找匹配的catch块。
- 如果在任一函数中都找不到匹配的catch块,程序将调用terminate()结束程序。
#include <iostream>void Fun3() {throw 0xCC; }void Fun2() {try{Fun3();}catch (char exception){std::cout << exception << std::endl;}}void Fun1() {try{Fun2();}catch (float exception){std::cout << "Fun1 Exception" << std::endl;}}int main() {try{Fun1();}catch (...){std::cout << "Main Exception" << std::endl;}return 0; }
异常规划
- 异常规范(exception specification)是C++中的一种功能,它允许开发者指明一个函数可能抛出哪些异常。
- 自从C++11起,异常规范已经不再被推荐使用,取而代之的是noexcept关键字。
- void someFunction() throw(int, char); // 只能抛出int型和char型异常
- void someFunction() noexcept; // 不会抛出异常
-
#include <iostream> #include <vector>//该函数不会抛出任何异常 void Fun1() throw() {}void Fun2() noexcept {}void Fun3() throw(int) {}void Fun4() throw(char) {}void Fun5() throw(char, int) {}int main() {try{Fun3();}catch (int exception){std::cout << exception << std::endl;}try{Fun4();}catch (char exception){std::cout << exception << std::endl;}try{Fun5();}catch (char exception){std::cout << exception << std::endl;}catch (int exception){std::cout << exception << std::endl;}return 0; }
标准异常
- std::exception 是各种标准异常类的基础,提供了一个异常层次结构。
-
std::logic_error
- 逻辑错误表示程序的逻辑不当导致的问题,这通常是可以预防的错误。
- std::domain_error: 当一个数学函数接收到一个不在其定义域内的参数时抛出。
- std::invalid_argument: 当传递给函数的参数无效时抛出。
- std::length_error: 当创建过大的 std::string 或者 std::vector 时抛出。
- std::out_of_range: 当通过 at 访问 std::vector 或 std::string 而下标超出范围时抛出。
-
std::runtime_error
- 运行时错误,表示在程序运行时发现的错误,通常是难以预防的。
- std::overflow_error: 当算术运算超过表示范围时抛出。
- std::underflow_error: 当算术运算结果在正确的表示范围内,但非正规化时抛出。
- std::range_error: 当计算的结果不在可表示的范围内时抛出。
- std::system_error: 用于报告系统错误的异常。
-
std::bad_alloc
当动态内存分配失败时(如 new 表达式),std::bad_alloc 被抛出。
-
std::bad_cast
使用动态转换 (dynamic_cast) 转换到不兼容的类型时,抛出 std::bad_cast。
-
std::bad_typeid
当使用类型信息功能(如 typeid 操作符)并且操作的对象是未定义类型时,抛出 std::bad_typeid 异常。
-
std::bad_function_call
当调用一个空的 std::function 对象时,抛出 std::bad_function_call 异常。
-
#include <iostream>int main() {try{long long* p = new long long[0xFFFFFFF];}catch (const std::exception& e){std::cout << e.what() << std::endl;}return 0; }
自定异常
-
#include <iostream>class myException :public std::exception { public:myException(std::string message): m_Message(message){}virtual const char* what() const{return m_Message.c_str();}private:std::string m_Message; };int main() {try{myException obj("cc exception");throw obj;}catch (const std::exception& e){std::cout << e.what() << std::endl;}return 0; }
相关文章:
C/C++ - 异常处理
目录 错误处理 异常处理 异常传播 异常规划 标准异常 自定异常 错误处理 在C语言中,错误通常通过函数的返回值来表示。 错误返回值 对于能返回特殊值(如NULL或负值)的函数,在调用时检查这些值来处理错误。 #include <st…...
十、项目开发总结报告(软件工程)
1.引言 1.1编写目的 1.2项目背景 1.3定义 1.4参考资料 2.开发结果 2.1产品 2.2主要功能及性能 2.3所用工时 2.4所用机时 2.5进度 2.6费用 3.评价 3.1生产率评价 3.2技术方案评价 3.3产品质量评价 4ÿ…...
在 VMware 虚拟机上安装 CentOS系统 完整(全图文)教程
一、前期准备: 1.安装VMware 虚拟机软件(不在讲解,可自行去下载安装)。官网:https://customerconnect.vmware.com/cn/downloads/details?downloadGroupWKST-PLAYER-1750&productId1377&rPId111471 2.下载iso…...
吉他学习:右手拨弦方法,右手拨弦训练 左手按弦方法
第六课 右手拨弦方法https://m.lizhiweike.com/lecture2/29362775 第七课 右手拨弦训练https://m.lizhiweike.com/lecture2/29362708...
【初识爬虫+requests模块】
爬虫又称网络蜘蛛、网络机器人。本质就是程序模拟人使用浏览器访问网站,并将需要的数据抓取下来。爬虫不仅能够使用在搜索引擎领域,在数据分析、商业领域都得到了大规模的应用。 URL 每一个URL指向一个资源,可以是一个html页面,一…...
微信小程序(三十八)滚动容器
注释很详细,直接上代码 上一篇 新增内容: 1.滚动触底事件 2.下拉刷新事件 源码: index.wxml <view class"Area"> <!-- scroll-y 垂直滚动refresher-enabled 允许刷新bindrefresherrefresh 绑定刷新作用函数bindscrollto…...
Python学习之路-Tornado基础:数据库
Python学习之路-Tornado基础:数据库 简介 与Django框架相比,Tornado没有自带ORM,对于数据库需要自己去适配。我们使用MySQL数据库。 在Tornado3.0版本以前提供tornado.database模块用来操作MySQL数据库,而从3.0版本开始,此模块…...
Golang的for循环变量和goroutine的陷阱,1.22版本的更新
先来看一段golang 1.22版本之前的for循环的代码 package mainimport "fmt"func main() {done : make(chan bool)values : []string{"chen", "hai", "feng"}for _, v : range values {fmt.Println("start")go func() {fmt.P…...
List 差集
文章目录 基本类型对象类型 基本类型 ListUtils.subtract 方法用于计算两个集合的差集,即返回 list1 中有但 list2 中没有的元素。 其中,list1 指向第一个集合,list2 指向第二个集合。该方法返回一个新的 List 对象,它包含所有在…...
ArcGIS的UTM与高斯-克吕格投影分带要点总结
UTM(通用横轴墨卡托投影、等角横轴割椭圆柱投影)投影分带投影要点: 1)UTM投影采用6度分带 2)可根据公式计算,带数(经度整数位/6)的整数部分31 3)北半球地区࿰…...
华为第二批难题一:基于预训练AI模型的元件库生成
我的理解:华为的这个难道应该是想通过大模型技术,识别元件手册上的图文内容,与现有建库工具结合,有潜力按标准生成各种库模型。 正好,我们正在研究,利用知识图谱技术快速生成装配模型,其中也涉…...
Android AOSP源码研究之万事开头难----经验教训记录
文章目录 1.概述2.Android源下载1.配置环境变量2.安装curl3.下载repo并授权4.创建一个文件夹保存源码5.设置repo的地址并配置为清华源6.初始化仓库7.指定我们需要下载的源码分支并初始化 2.1 使用移动硬盘存放Android源码的坑2.2 解决方法 3.Android源码编译4.Android源烧录 1.…...
动态数据源
一、部署 1、导入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.1.0</version></dependency>2、编写yml 配置文件 spring:datasource:dyna…...
2024.1.29力扣每日一题——自由之路
2024.1.29 题目来源我的题解方法一 动态规划 题目来源 力扣每日一题;题序:514 我的题解 方法一 动态规划 定义 dp[i][j] 表示从前往后拼写出 key的第 i个字符, ring 的第 j个字符与 12:00 方向对齐的最少步数(下标均从 0 开始&…...
Qt应用软件【协议篇】UDP示例
UDP协议简介 UDP(用户数据报协议)是一种无连接的网络协议,提供了简单但是不可靠的消息传输服务。与TCP不同,UDP不保证数据包的顺序、重复性或者可达性,但它在速度和效率上具有优势,特别适合那些对实时性要求高的应用,如视频流、在线游戏等。 Qt中的UDP编程 在Qt中,U…...
MyBatis之动态代理实现增删改查以及MyBatis-config.xml中读取DB信息文件和SQL中JavaBean别名配置
MyBatis之环境搭建以及实现增删改查 前言实现步骤1. 编写MyBatis-config.xml配置文件2. 编写Mapper.xml文件(增删改查SQL文)3. 定义PeronMapper接口4. 编写测试类1. 执行步骤2. 代码实例3. 运行log 开发环境构造图总结 前言 上一篇文章,我们…...
百面嵌入式专栏(面试题)内存管理相关面试题1.0
沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍内存管理相关面试题 。 一、内存管理相关面试题 page数据结构中的_refcount和_mapcount有什么区别?匿名页面和高速缓存页面有什么区别?page数据结构中有一个锁,我们称为页锁,请问trylock_page()和loc…...
SpringMVC 1.请求参数检查 2.全局异常处理 3.请求参数封装为Pojo
ErrorEnum.java // 枚举所有的错误 package com.example.demo.enums;import lombok.Getter;public enum ErrorEnum {SYSTEM_ERROR(-1, "系统错误"),PARAM_ERROR(-2, "参数错误"),OK(0, "成功"),;Getterprivate final int code;Getterprivate fi…...
7机器人位姿的数学描述与坐标变
由上次刚体的空间转动直接切换为机器人相关术语。 1.机器人位姿的数学描述与坐标变换 1.1位姿描述 {B}相对于{A}的姿态描述用3x3矩阵表示为: 式中为三个单位正交主矢量,分别表示刚体坐标系{B}的三个坐标轴XBYBZB在参考系{A}中的方位,∠XBXA表…...
基于ESP8266 开发板(MCU)遥控小车
遥控小车 遥控界面 【项目源码】 第一版ESP8266 https://github.com/liyinchigithub/esp8266_car_webServerhttps://github.com/liyinchigithub/esp8266_car_webServer 第二版ESP32 GitHub - liyinchigithub/esp32-wroom-car: 嵌入式单片机 ESP32 Arduino 遥控小车&a…...
加油卡小程序玩法全解析:刚需场景破局,从充值裂变到合规运营全攻略
国内私家车与新能源车主群体持续扩容,加油、充电作为高频刚性消费场景,自带稳定流量与强付费意愿,加油卡小程序凭借轻量化、易传播、直达用户的优势,成为加油站、第三方车主服务平台、车企布局私域流量的核心载体。不同于潮玩等娱…...
Xcode打包上传App Store Connect失败?可能是这些配置没做好(含解决方案)
Xcode打包上传App Store Connect失败排查指南:从配置到解决方案 每次提交应用上架都是iOS开发者必经的考验,而Xcode打包上传过程中遇到的"无效二进制文件"错误堪称拦路虎。这种错误往往不会给出明确提示,而是通过邮件通知或在App S…...
解决Redis测试环境搭建难题的try.redis工具:零配置交互式终端功能全解析
解决Redis测试环境搭建难题的try.redis工具:零配置交互式终端功能全解析 【免费下载链接】try.redis A demonstration of the Redis database. 项目地址: https://gitcode.com/gh_mirrors/tr/try.redis 在日常开发中,开发者常常面临Redis测试环境…...
PyTorch 2.8镜像效果展示:使用OpenCV对VideoLDM输出做运动模糊增强处理
PyTorch 2.8镜像效果展示:使用OpenCV对VideoLDM输出做运动模糊增强处理 1. 效果展示概览 在视频生成领域,运动模糊效果是提升视频真实感的关键因素之一。本文将展示如何利用PyTorch 2.8镜像环境,结合OpenCV对VideoLDM生成的原始视频进行运动…...
dfs:飞机降落
题目:P9241 [蓝桥杯 2023 省 B] 飞机降落 - 洛谷 做题目之前一定要先看数据范围。这道题的数据范围,T,N均<10,可以用暴力搜索。 这道题是排序,假设有3辆飞机。顺序可以是123,132,213,231&am…...
Python边缘部署不是“复制粘贴”!12个生产环境真实报错日志溯源分析(附可复用诊断矩阵表)
第一章:Python边缘部署的本质认知与误区破除Python边缘部署不是将桌面或服务器环境简单“搬移”到嵌入式设备,而是面向资源受限、实时性敏感、网络不可靠、运维通道受限等物理约束下的系统性重构。其本质是**在算力、内存、存储、功耗与可靠性之间达成动…...
STM32HAL库项目实战:我把W5500和MQTTClient库‘缝’起来,实现了阿里云OTA升级前传
STM32HAL库与W5500深度整合:从MQTT云连接到OTA升级的工程实践 在嵌入式设备智能化浪潮中,远程固件升级(OTA)已成为工业设备的标配功能。本文将揭示如何基于STM32HAL库和W5500以太网芯片构建可靠的云连接通道,为后续OTA升级打下坚实基础。不同…...
Qwen3.5-4B-Claude-Opus高性能推理教程:Q4_K_M量化下GPU吞吐量实测分析
Qwen3.5-4B-Claude-Opus高性能推理教程:Q4_K_M量化下GPU吞吐量实测分析 1. 模型概述 Qwen3.5-4B-Claude-4.6-Opus-Reasoning-Distilled-GGUF是基于Qwen3.5-4B架构的推理蒸馏模型,特别强化了结构化分析、分步骤回答以及代码与逻辑类问题的处理能力。该版…...
智能记账本:OpenClaw+Qwen3.5-9B自动归类信用卡消费邮件
智能记账本:OpenClawQwen3.5-9B自动归类信用卡消费邮件 1. 为什么需要自动化记账工具 每次收到银行消费短信时,我都会陷入两难:手动记账太繁琐,不记账又会导致月度消费分析失真。传统记账软件需要手动输入金额和分类,…...
别再手动算内存了!用STM32CubeIDE的Build Analyzer,5分钟摸清你的H743芯片还剩多少FLASH和RAM
深度解析STM32CubeIDE内存分析:从Build Analyzer到高效内存管理实战 在嵌入式开发的世界里,内存就像是一块珍贵的画布——有限且昂贵。想象一下,当你精心设计的STM32H743程序在关键时刻崩溃,而问题可能仅仅是因为某个全局变量悄悄…...
