RAII (Resource Acquisition Is Initialization) — это идиома 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("Cannot open file"); file << data; } // файл закроется здесь
При возникновении исключений деструктор всё равно вызовется, ресурсы не уйдут в утечку. Если не использовать RAII, можно столкнуться с утечками памяти и файловых дескрипторов.
Можно ли гарантировать отсутствие утечек памяти в C++, используя только try/catch?
Нет, нельзя. Просто использование try/catch не гарантирует освобождение ресурсов. Гарантию дает только RAII.
int* arr = new int[10]; try { // Работа с arr throw std::runtime_error("Oops"); } catch (...) { // arr не освобожден, если не было delete[] } // arr утек!
История
В крупном проекте по графике периодически происходили падения из-за исчерпания файловых дескрипторов. Оказалось, файлы открывались в функции без обёртывания в RAII (std::fstream), и при выбрасывании исключения ресурсы не освобождались.
История
В обработчике запросов веб-сервера использовалась сырая память без обертки в smart-pointer – в случае выбрасывания исключения память не освобождалась, что приводило к деградации производительности и падениям.
История
В проекте обработки изображений создавались временные файлы без обертки объектами. При выбрасывании исключений файлы не удалялись, что приводило к переполнению /tmp на сервере через несколько месяцев непрерывной работы.