Даны два фрагмента на C++: один использует raw pointers, второй — smart pointers (unique_ptr/shared_ptr). Проанализируйте поведение при копировании/перемещении и возможные утечки или двойное освобождение.

17 Ноя в 09:51
3 +1
0
Ответы
1
Кратко — сравнение поведения при копировании/перемещении и возможные утечки/двойное освобождение.
1) Raw pointers (сырые указатели)
- Копирование: при присваивании копируется адрес (шаловое/shallow copy); владение не отслеживается.
- Перемещение: не существует автоматической семантики перемещения — перемещение фактически то же, что копирование адреса.
- Утечки/двойное освобождение:
- Если ни один не вызовет `delete` — утечка.
- Если два независимых кода вызовут `delete` для одного и того же адреса — двойное освобождение (UB).
- Пример проблемы: `T* p = new T; T* q = p; delete p; delete q;` → UB.
- Вывод: ответственность за `delete` полностью на программисте; плохая устойчивость к исключениям.
2) std::unique_ptr - Копирование: запрещено (нет copy-конструктора/оператора), попытка копирования — ошибка компиляции.
- Перемещение: разрешено; операция перемещения передаёт владение, исходный указатель становится пустым (равен `nullptr`).
- Формально: после `u2 = std::move(u1);` владение у `u2`, `u1` пуст.
- Утечки/двойное освобождение:
- Правильное использование исключает двойное удаление и автоматизирует освобождение при выходе из области видимости.
- Можно получить двойное удаление, если вручную создать два `unique_ptr` из одного сырого указателя: `std::unique_ptr a(p); std::unique_ptr b(p);` → двойное удаление.
- Подходит для единоличного владения; хорош для RAII и безопасности при исключениях.
3) std::shared_ptr - Копирование: разрешено; при копировании увеличивается счётчик ссылок (use count).
- Если был один shared_ptr и созданы ещё две копии, итоговый счётчик: use_count =3=3=3.
- Перемещение: при перемещении счётчик не увеличивается, владение перемещается в новый объект.
- Утечки/двойное освобождение:
- Объект удаляется автоматически, когда счётчик обращений достигает нуля (последний `shared_ptr` уничтожается).
- Двойного удаления не будет при корректной работе счётчика.
- Опасность: циклические ссылки через `shared_ptr` (A → shared_ptr, B → shared_ptr) приводят к тому, что счётчики никогда не станут нулём → утечка.
- Решение циклов: использовать `std::weak_ptr` для «слабых» ссылок, не увеличивающих счётчик.
- Примечание: счётчик обычно атомарен — накладные расходы и потенциальные затраты в многопоточной среде.
Резюме / рекомендации
- Для единоличного владения используйте `std::unique_ptr` (перемещение для передачи владения).
- Для совместного владения используйте `std::shared_ptr` и ломайте циклы через `std::weak_ptr`.
- Никогда не создавайте несколько умных указателей из одного сырого указателя (это приведёт к двойному удалению).
- Если используете сырые указатели, явно договоритесь о владении и освобождении; лучше избегать `new`/`delete` вручную в современном C++.
- Проверки: счётчик `shared_ptr` можно посмотреть через `use_count()`; ожидаемое завершение удаления при достижении use_count =0=0=0.
17 Ноя в 09:59
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир