当前位置: 首页 > news >正文

第1讲:彻底解决C++中资源泄露

一、需要解决的问题

1. 内存泄露

2. 文件句柄泄露(文件打开后未关闭)

3. 锁未释放(加锁后未解锁)

4. 循环中忘记continue

5. 抛出异常后,资源未释放

6. 一对函数必须配合使用时,不小心导致未配对

二、解决方案

#ifndef XJ_DEFER
#define XJ_DEFER(name, func) auto name = std::unique_ptr<void, std::function<void(void*)>>(nullptr, [&](void*){func;});
#endif

XJ_DEFER 宏的核心原理是利用 std::unique_ptr 的 “资源自动释放” 特性,通过自定义删除器在对象离开作用域时执行清理逻辑。这种方式能有效避免因人为疏忽(如忘记释放、分支跳转遗漏)导致的资源泄露问题,尤其适合管理内存、句柄、锁、文件等需要手动释放的资源。

三、示例说明

1. 解决内存泄露(new 后忘记 delete)

问题代码:使用 new 分配内存后,因分支跳转或异常导致忘记 delete,造成内存泄露。

void func() {int* ptr = new int(10); // 分配堆内存if (some_condition) {return; // 此处返回,导致 ptr 未释放,内存泄露}// ... 其他逻辑delete ptr; // 正常路径才释放,异常/分支跳转时遗漏
}

改进代码:用 XJ_DEFER 在内存分配后绑定释放逻辑,作用域结束时自动执行 delete。

void func() {int* ptr = new int(10);XJ_DEFER(defer_delete, delete ptr); // 绑定释放逻辑,作用域结束时自动执行if (some_condition) {return; // 即使返回,defer_delete 会在作用域结束时释放 ptr}// ... 其他逻辑// 无需手动 delete,defer 会自动处理
}

2 解决句柄泄露(如 Windows 句柄未关闭)

问题代码:获取系统句柄(如文件句柄)后,因逻辑遗漏未关闭,导致句柄泄露。

#include <windows.h>void func() {HANDLE hFile = CreateFileA("test.txt", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);if (hFile == INVALID_HANDLE_VALUE) {return; // 句柄无效时返回,无需处理}if (some_condition) {return; // 此处返回,hFile 未关闭,句柄泄露}// ... 其他逻辑CloseHandle(hFile); // 正常路径才关闭,分支跳转时遗漏
}

改进代码:用 XJ_DEFER 绑定句柄关闭逻辑,确保作用域结束时释放。

#include <windows.h>void func() {HANDLE hFile = CreateFileA("test.txt", GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);if (hFile == INVALID_HANDLE_VALUE) {return;}XJ_DEFER(defer_close, CloseHandle(hFile)); // 绑定句柄关闭逻辑if (some_condition) {return; // 即使返回,defer_close 会自动关闭 hFile}// ... 其他逻辑// 无需手动 CloseHandle,defer 会自动处理
}

3. 解决锁未释放

问题代码:手动锁定互斥锁后,因异常或分支跳转忘记解锁,导致死锁。

#include <mutex>std::mutex mtx;void func() {mtx.lock(); // 手动加锁if (some_condition) {return; // 此处返回,mtx 未解锁,其他线程会死锁}// ... 其他逻辑mtx.unlock(); // 正常路径才解锁,分支跳转时遗漏
}

改进代码:用 XJ_DEFER 绑定解锁逻辑,确保作用域结束时释放锁。

#include <mutex>std::mutex mtx;void func() {mtx.lock();XJ_DEFER(defer_unlock, mtx.unlock()); // 绑定解锁逻辑if (some_condition) {return; // 即使返回,defer_unlock 会自动解锁}// ... 其他逻辑// 无需手动 unlock,defer 会自动处理
}

4. 解决文件打开未关闭(FILE* 未关闭)

问题代码:用 fopen 打开文件后,因逻辑遗漏未调用 fclose,导致文件描述符泄露。

#include <cstdio>void func() {FILE* fp = fopen("test.txt", "r");if (!fp) {return;}if (some_condition) {return; // 此处返回,fp 未关闭,文件描述符泄露}// ... 其他逻辑fclose(fp); // 正常路径才关闭,分支跳转时遗漏
}

改进代码:用 XJ_DEFER 绑定文件关闭逻辑,确保作用域结束时关闭。

#include <cstdio>void func() {FILE* fp = fopen("test.txt", "r");if (!fp) {return;}XJ_DEFER(defer_fclose, fclose(fp)); // 绑定文件关闭逻辑if (some_condition) {return; // 即使返回,defer_fclose 会自动关闭 fp}// ... 其他逻辑// 无需手动 fclose,defer 会自动处理
}

5. 解决循环中忘记 continue 导致的资源未释放

问题代码:循环中满足条件时应跳过后续逻辑(continue),但忘记写 continue,导致资源重复处理或泄露。

#include <vector>
#include <cstdio>void func(const std::vector<int>& data) {for (int val : data) {FILE* fp = nullptr;if (val < 0) {fp = fopen("negative.txt", "a");if (!fp) continue;// ... 处理负数逻辑// 忘记写 continue,导致后续“正数逻辑”错误执行} else {fp = fopen("positive.txt", "a");if (!fp) continue;// ... 处理正数逻辑}fclose(fp); // 若上面忘记 continue,可能导致 fp 被重复使用或未关闭}
}

改进代码:用 XJ_DEFER 确保文件在当前循环迭代中自动关闭,即使忘记 continue,也不会泄露文件句柄。

#include <vector>
#include <cstdio>void func(const std::vector<int>& data) {for (int val : data) {FILE* fp = nullptr;if (val < 0) {fp = fopen("negative.txt", "a");if (!fp) continue;XJ_DEFER(defer_neg_close, fclose(fp)); // 绑定当前 fp 的关闭逻辑// ... 处理负数逻辑// 即使忘记写 continue,离开 if 作用域时,defer_neg_close 会自动关闭 fp} else {fp = fopen("positive.txt", "a");if (!fp) continue;XJ_DEFER(defer_pos_close, fclose(fp)); // 绑定当前 fp 的关闭逻辑// ... 处理正数逻辑}// 无需手动 fclose,defer 会在对应作用域结束时自动处理}
}
http://www.dtcms.com/a/554770.html

相关文章:

  • CentOS 7上运行C程序
  • 网站建设有什么证.net程序员网站开发工程师
  • 安信可(Ai-Thinker)WiFi系列模块全解析:选型指南与应用洞察
  • 科技建站网站源码黄金网站app视频播放画质选择
  • 品牌网站设计图片企业软件管家
  • NetSuite 如何删除未生成的Memorized Transaction?
  • 秦皇岛优化网站排名邹城网站建设
  • 扁平化网站导航ui模板电子商务网站建设与管理理解
  • 有什么网站可以做毕业影像页面设计源代码
  • 金泽通 打造数字金融与商业融合新模式
  • 【算法专题训练】29、树的深度优先遍历
  • Rust + WebAssembly 实现多人在线共享白板:从设计到性能验证
  • 电脑什么网站可以做长图攻略阳光家园广州网站
  • 新网站建设平台上海做网站运维的公司
  • javan
  • 在VSCode+Guider基础上 运行Button圆角demo
  • 【更新至 91 个】分子动力学模拟 + 数据处理程序
  • LIBTORCH 再配置总结
  • element-ui源码阅读-样式
  • 重生归来,我要成功 Python 高手--day31 线性回归
  • 网站开发python和c 哪个好住房和城乡建设部科技发展促进中心网站
  • 黑彩网站建设立即优化在哪里
  • 怎么在网上建网站啊东莞网站优化方案
  • 图片做网站连接在线切图网站
  • 模拟 1576. 替换所有的问号
  • 通辽网站开发0475seo做网站卖赚钱吗
  • 品牌营销网站建设流程一学一做短视频网站
  • 养殖网站 模板谷歌搜索引擎seo
  • 智能课堂课程系统源码 – 多端自适应_支持讲师课程
  • 杰理芯片SDK开发-开发环境搭建Code::Blocks