Опасные ловушки C++: умные указатели, которые не всегда умные — 24 июля 2026 г. в 10:12:06.744
Опасные ловушки C++: умные указатели, которые не всегда умные 👋 Приветствую в мире цифровой безопасности! В прошлый раз разобрали многопоточность. Сегодня - про smart pointers. Они избавляют от большинства утечек памяти, но создают свои ловушки, из-за которых объекты могут жить вечно или исчезать раньше времени. ⏺shared_ptr и циклические ссылки: если два объекта владеют друг другом через std::shared_ptr, счётчик ссылок никогда не станет нулём, а память не освободится: struct B; struct A { std::shared_ptr<B> b; }; struct B { std::shared_ptr<A> a; }; Оба объекта будут существовать до завершения процесса. Такие утечки сложно заметить, потому что формально delete нигде не забыли. ⏺Решение: в одну сторону использовать std::weak_ptr. Он не увеличивает счётчик ссылок и позволяет безопасно проверить, существует ли объект: struct B { std::weak_ptr<A> a; }; if (auto p = weak.lock()) { // объект ещё существует } ⏺Не создавайте два shared_ptr из одного сырого указателя: int* p = new int(42); std::shared_ptr<int> a(p); std::shared_ptr<int> b(p); // ошибка Каждый shared_ptr считает себя единственным владельцем. В итоге оба вызовут delete, что приведёт к двойному освобождению памяти. Правильно передавать уже существующий shared_ptr, а не исходный указатель. ⏺unique_ptr после std::move больше использовать нельзя: auto p = std::make_unique<int>(10); auto q = std::move(p); // p == nullptr После передачи владения исходный указатель становится пустым. Попытка разыменовать его закончится неопределённым поведением. ⏺make_shared быстрее и безопаснее: auto obj = std::make_shared<MyClass>(); make_shared делает одно выделение памяти сразу под объект и управляющий блок. Это быстрее, экономит память и исключает некоторые сценарии утечки при возникновении исключений. ⏺AddressSanitizer помогает находить ошибки памяти: g++ -fsanitize=address -g app.cpp -o app ./app ASan обнаруживает use-after-free, двойное освобождение памяти, выход за границы массива и многие другие ошибки ещё во время тестирования, когда они могут не проявляться в обычном запуске. 🤖Бесплатный ChatGPT

