Проанализируйте возможную утечку памяти в C++ при использовании shared_ptr: struct Node{ shared_ptr next; }; Node a,b; a.next = b; b.next = a; — почему возникает проблема и как её решить

25 Ноя 2025 в 11:36
18 +1
0
Ответы
1
Проблема: создаётся циклическая ссылка сильных указателей — каждый объект владеет другим через `shared_ptr`, поэтому счётчик ссылок у обоих никогда не обнуляется и память не освобождается.
Почему так происходит (коротко): `shared_ptr` реализует подсчёт ссылок. При
создании двух `shared_ptr` на узлы их счётчики равны 111. После `a->next = b;` счётчик `b` становится 222. После `b->next = a;` счётчик `a` становится 222. При выходе из области видимости внешних `shared_ptr` счётчики останутся 111 (взаимные ссылки) и не достигнут 000, деструкторы не вызовутся — утечка.
Решение: разорвать циклическую сильную ссылку — используйте `std::weak_ptr` для ненесущего (observer/back) указателя. Пример:
Плохо (утечка):
struct Node {
std::shared_ptr next;
};
auto a = std::make_shared();
auto b = std::make_shared();
a->next = b;
b->next = a; // цикл сильных ссылок — утечка
Хорошо (исправлено):
struct Node {
std::weak_ptr next; // ненесущая ссылка
};
auto a = std::make_shared();
auto b = std::make_shared();
a->next = b; // хранит слабую ссылку
b->next = a;
if (auto nx = a->next.lock()) {
// доступ к следующему: nx — shared_ptr, проверяем его существование
}
Альтернативы: явно разрывать цикл вызовом `reset()`, использовать `unique_ptr` для владения в одном направлении, или хранить сырые/observer-указатели в не-владельческих связях. В большинстве случаев корректный и безопасный способ — заменить одну сторону цикла на `weak_ptr`.
25 Ноя 2025 в 11:43
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир