0

0

怎样编写不会泄漏资源的异常安全代码 智能指针与异常安全实践

P粉602998670

P粉602998670

发布时间:2025-07-31 10:24:02

|

890人浏览过

|

来源于php中文网

原创

使用智能指针自动释放资源,如 std::unique_ptr 和 std::shared_ptr,通过 raii 机制确保异常时资源自动释放;2. 避免裸指针和手动 delete,防止因异常跳过清理代码导致泄漏;3. 异常安全的函数设计应保证状态不被破坏,资源正确释放,并将资源封装在对象中;4. 容器中应使用智能指针而非裸指针,以确保插入异常时资源仍能正确释放。

怎样编写不会泄漏资源的异常安全代码 智能指针与异常安全实践

写异常安全的代码,关键在于保证在程序抛出异常时,资源不会泄漏、数据结构不会损坏。尤其是在C++中,手动管理资源(如内存、文件句柄)非常常见,如果处理不当,很容易出现资源泄漏问题。而智能指针就是解决这个问题的重要工具之一。

怎样编写不会泄漏资源的异常安全代码 智能指针与异常安全实践

1. 使用智能指针自动释放资源

C++标准库提供了几种智能指针类型,其中最常用的是 std::unique_ptrstd::shared_ptr。它们通过 RAII(资源获取即初始化)机制,在对象生命周期结束时自动释放所管理的资源。

怎样编写不会泄漏资源的异常安全代码 智能指针与异常安全实践
  • std::unique_ptr:适用于独占所有权的场景,效率高,不允许多个指针共享同一资源。
  • std::shared_ptr:适用于多个指针可能共享一个资源的情况,内部使用引用计数来决定何时释放资源。

例如:

void process_data() {
    std::unique_ptr data(new Data());
    // 如果下面这行抛出异常,data会在离开作用域时自动释放
    data->load_from_file("input.txt");
}

使用智能指针可以避免手动调用 delete,从而防止因异常跳过清理代码而导致的资源泄漏。

怎样编写不会泄漏资源的异常安全代码 智能指针与异常安全实践

2. 避免裸指针和手动 delete

很多资源泄漏的问题都来源于使用了“裸指针”(raw pointer),然后在代码中手动调用 delete。一旦函数中间抛出异常,这些 delete 很可能不会执行。

比如:

void bad_example() {
    Data* data = new Data();
    data->load_from_file("input.txt");  // 可能抛出异常
    delete data;
}

如果 load_from_file 抛出异常,delete data; 就不会被执行,导致内存泄漏。这种情况应该改用智能指针:

Batch GPT
Batch GPT

使用AI批量处理数据、自动执行任务

下载
void good_example() {
    auto data = std::make_unique();
    data->load_from_file("input.txt");  // 异常安全,离开作用域会自动释放
}

3. 异常安全的函数设计原则

编写异常安全的函数时,需要考虑以下几点:

  • 函数抛出异常后,不能破坏已有状态(强异常安全)。
  • 所有资源必须在异常发生时正确释放。
  • 尽量把资源封装在对象中,利用析构函数自动释放。

举个例子,如果你要修改某个对象的状态,并且过程中需要用到临时资源:

void update_config(Config& config) {
    auto temp_file = std::make_unique("temp.cfg");
    write_temp_config(temp_file->path(), config);  // 可能抛异常
    config.load_from(temp_file->path());           // 也可能抛异常
}

在这个例子中,即使 write_temp_configload_from 抛出异常,TemporaryFile 对象也会在析构时删除临时文件,不会造成资源残留。


4. 注意容器与异常安全的交互

STL 容器(如 vector, map)本身是异常安全的,但当你往容器里放裸指针时,就要特别小心:

  • 如果插入过程中抛出异常,裸指针可能已经分配但未被释放。
  • 更好的做法是使用智能指针包装资源后再放入容器。

例如:

std::vector> widgets;
widgets.push_back(std::make_unique());

这样即使在插入过程中发生异常,已有的智能指针仍会被正确释放,不会有泄漏。


基本上就这些。异常安全的核心思路就是“让资源的生命周期绑定到对象上”,只要能做到这一点,大多数资源泄漏问题都能避免。

相关专题

更多
treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

529

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

6

2025.12.22

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

73

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

25

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

36

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

31

2025.11.27

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

266

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.12.29

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.1万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号