Как правильно управлять ресурсами и избежать проблем с памятью
Что такое ресурс?
Это то, что вы должны использовать, а затем вернуть тому, кто одолжил вам это. В программировании это может быть дескриптор файла, дескриптор сокета, блокировка мьютекса и т. д.
В C++ стабильность и корректность программного обеспечения сильно зависят от управления ресурсами. Неправильное обращение с ресурсами может привести к утечкам памяти, утечкам файловых дескрипторов или другим утечкам ресурсов.
В этой статье мы проанализируем некоторые советы, взятые из книги Effective C++ Скотта Мейерса [1]».
Совет 1: Оберните ресурс в объекты
Пункт 13.Используйте объекты для управления ресурсами.
Effective C++, Скотт Мейерс, 2005 г.
В C++ настоятельно рекомендуется использовать объекты для управления ресурсами, так как в этом случае используются возможности идиомы RAII (Resource Acquisition Is Initialization).
Идиома RAII — это фундаментальный метод C++, который связывает срок службы объекта с приобретением и высвобождением ресурса. Он использует детерминированное уничтожение объектов C++, чтобы гарантировать надлежащую очистку ресурсов даже при наличии исключений или преждевременных возвратов.
Идея заключается в том, что, инкапсулируя ресурсы в объекты, принцип RAII обеспечивает автоматическое управление ресурсами.
Умные указатели
Лучший способ обернуть ресурсы в объекты в C++ — это умные указатели.
Они инкапсулируют указатель внутри объекта, который обрабатывает получение и освобождение ресурсов с помощью конструкторов и деструкторов.
Два наиболее часто используемых типа интеллектуальных указателей: std::unique_ptr
(для монопольного владения) и std::shared_ptr
(для совместного владения).
// Managing Dynamic Memory with std::unique_ptr void processData() { std::unique_ptr<int> ptr(new int(42)); // Acquire resource // Perform some operations with the resource // ... // No need to manually release the resource // The unique_ptr's destructor will automatically clean up the memory } void useSharedResource() { // Acquire resource std::shared_ptr<DatabaseConnection> connection(new DatabaseConnection()); //…