ПрограммированиеC++ разработчик

Расскажите, как работают RAII и исключения в C++? Почему важно правильно реализовывать управление ресурсами?

Проходите собеседования с ИИ помощником Hintsage

Ответ.

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 на сервере через несколько месяцев непрерывной работы.