使用RAII机制可确保异常安全下的资源释放,推荐智能指针如std::unique_ptr管理内存,自定义类封装非内存资源,在构造函数获取资源、析构函数释放,避免手动清理。

在C++中,异常处理过程中释放动态资源的关键在于避免资源泄漏,尤其是在异常发生时传统的清理代码可能无法执行。直接依赖
try-catch块中的
delete或
free来释放资源容易出错,推荐使用RAII(Resource Acquisition Is Initialization)机制来自动管理资源。
使用智能指针管理动态内存
智能指针是C++标准库提供的RAII工具,能自动在对象生命周期结束时释放资源,即使异常发生也能保证释放。
- std::unique_ptr:用于独占所有权的动态对象,异常抛出时会自动调用析构函数释放内存。
- std::shared_ptr:适用于共享所有权的场景,通过引用计数管理资源释放。
示例:
#include#include void riskyFunction() { auto ptr = std::make_unique
(42); // 自动管理 if (true) { throw std::runtime_error("出错了!"); } // 即使抛出异常,ptr 析构时会自动释放内存 }
自定义资源的RAII封装
对于非内存资源(如文件句柄、互斥锁等),可以封装类,在构造函数中获取资源,析构函数中释放。
立即学习“C++免费学习笔记(深入)”;
示例:文件操作
class FileGuard {
FILE* file;
public:
FileGuard(const char* path, const char* mode) {
file = std::fopen(path, mode);
if (!file) throw std::runtime_error("无法打开文件");
}
~FileGuard() {
if (file) std::fclose(file);
}
FILE* get() { return file; }};
void processFile() {
FileGuard guard("test.txt", "r");
// 可能抛出异常
throw std::logic_error("处理失败");
// 函数退出时,guard 析构自动关闭文件
}
避免在异常路径中手动释放
不要依赖
catch
块中手动释放资源,这容易遗漏或重复释放。
错误做法:
void badExample() {
int* p = new int[100];
try {
riskyOperation();
delete[] p;
} catch (...) {
delete[] p; // 容易遗漏,代码重复
throw;
}
}
正确做法:使用
std::vector
或std::unique_ptr
替代原始指针。
基本上就这些。只要坚持使用RAII和标准库提供的资源管理工具,C++中的异常安全和资源释放就能自然达成,无需在每个
catch
中重复清理逻辑。










