Откуда берутся висячие ссылки
Вопрос
Приведите несколько способов получить висячую ссылку или указатель в C++ и расскажите, как их избегать.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Возврат ссылки или указателя на локальную переменную
Инвалидация при изменении контейнера: реаллокация vector, erase
Временный объект через функцию, возвращающую ссылку (`std::max` с временными)
Невладеющие типы (`string_view`, `span`) на умершие данные
Захват по ссылке в лямбде, которая переживает область видимости
Средства: возврат по значению, явное время жизни, санитайзеры, `-Wdangling-reference`
Что могут спросить следом
- Почему
std::string_viewна результат функции, возвращающей std::string, опасен? - Какие операции vector инвалидируют итераторы?
Разбор
Висячая ссылка появляется, когда объект умер, а ссылка или указатель на него ещё используется. Классика: вернуть ссылку на локальную переменную, она уничтожается на выходе из функции. Второй источник: контейнеры. После push_back вектор может перевыделить буфер, и все ссылки на элементы виснут; erase инвалидирует всё начиная с удалённого элемента. Третий: временные объекты. Продление жизни работает только при прямой привязке к const&, а const auto& m = std::max(std::string("a"), std::string("b")) висит, потому что max возвращает ссылку на временный аргумент. Четвёртый: невладеющие типы std::string_view и std::span, созданные от временной строки или вектора. Пятый: лямбда, захватившая локальные переменные по ссылке и вызванная позже, например в другом потоке. Избегаю так: возвращаю по значению, не храню ссылки на элементы через изменения контейнера, слежу, кто владеет данными у string_view, захватываю по значению в отложенных лямбдах, гоняю тесты с AddressSanitizer и включаю предупреждения вроде -Wdangling-reference в GCC 14.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Указатели и ссылки»
- Удалить узлы списка с заданными значениями
- Кольцевой буфер для логов
- Повернуть матрицу, хранящуюся одним буфером
- Указатель за конец массива
- sizeof массива-параметра
- nullptr против NULL в перегрузке
- Указатель «за последним»
- Что выведет: арифметика указателей и ссылки