История вопроса:
Обычные (сырые) указатели — традиционный механизм в C++ для работы с динамической памятью. Это универсальный абстрактный механизм, но, к сожалению, очень подвержен ошибкам: утечкам памяти, двойному удалению, ошибкам Dangling pointer. Поэтому с C++11 стандартная библиотека включает умные указатели — шаблонные классы (std::unique_ptr, std::shared_ptr, std::weak_ptr), которые автоматически управляют временем жизни объекта.
Проблема:
При использовании обычных указателей ответственность за выделение и освобождение памяти ложится на программиста. Ошибки в освобождении памяти приводят к утечкам (memory leaks), разрушению данных, падениям программы. Особенно сложные случаи встречаются в обработке исключений или при передаче указателей в другие функции.
Решение:
Умные указатели инкапсулируют выделенную память и автоматически освобождают её, когда владельцев больше нет. Они реализуют RAII. std::unique_ptr обеспечивает эксклюзивное владение, std::shared_ptr — разделённое, std::weak_ptr — неконтролирующее (для предотвращения "цикла ссылок").
Пример кода:
#include <memory> void foo() { std::unique_ptr<int> p = std::make_unique<int>(5); // память освободится даже при исключении // ... }
Ключевые особенности:
Можно ли использовать std::unique_ptr в массив, созданный через new[]?
Нет, для массивов используйте std::unique_ptr<T[]>: так будет вызван delete[] вместо delete.
std::unique_ptr<int[]> arr(new int[10]);
Стандартные умные указатели могут предотвратить все возможные утечки памяти?
Нет. Например, циклические ссылки между std::shared_ptr приведут к утечкам. Для разрыва таких циклов применяют std::weak_ptr.
Могут ли умные указатели "удалить" один и тот же объект дважды?
Нет, если не нарушать логику владения (не использовать сырые указатели!). Если вручную копировать сырой указатель, то уничтожение может произойти дважды.
Используются сырые указатели, память освобождается вручную, при выбросе исключения память не освобождается.
Плюсы:
Минусы:
Используется std::unique_ptr и std::make_unique для создания объектов и передачи их в функции.
Плюсы:
Минусы: