RAII(资源获取即初始化) 是C++中的一种习惯用法,用于通过对象的生命周期管理资源(文件、内存、套接字等)的生命周期。资源在对象的构造函数中分配,并在析构函数中释放。
#include <fstream> void save_data(const std::string& filename, const std::string& data) { std::ofstream file(filename); // RAII: 文件将自动关闭 if (!file) throw std::runtime_error("无法打开文件"); file << data; } // 文件在这里关闭
当发生异常时,析构函数仍然会被调用,资源不会泄漏。如果不使用RAII,可能会遇到内存和文件描述符的泄漏。
仅使用try/catch能否确保C++中没有内存泄漏?
不能。仅仅使用try/catch并不能保证资源得到释放。只有RAII才能保证这一点。
int* arr = new int[10]; try { // 操作arr throw std::runtime_error("哎呀"); } catch (...) { // 如果没有delete[],arr不会被释放 } // arr泄漏!
故事
在一个大型图形项目中,因文件描述符耗尽而导致的崩溃时有发生。发现文件在函数中打开而没有使用RAII(std::fstream)进行包装,导致抛出异常时资源未被释放。
故事
在网络服务器的请求处理程序中使用了原始内存,而没有使用智能指针进行包装 – 在抛出异常的情况下,内存未被释放,从而导致性能下降和崩溃。
故事
在图像处理项目中,创建了没有用对象包装的临时文件。在抛出异常时,文件没有被删除,导致服务器上的/tmp在几个月的连续运行后溢出。