0Pricing
C++ Academy · Урок

Время жизни ссылок и висячие ссылки

Избегайте висячих ссылок, внимательно анализируя время жизни объектов.

«Время жизни ссылок и висячие ссылки» — бесплатный урок C++ Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Что такое висячая ссылка

Ссылка становится висячей, когда объект, на который она ссылается, уничтожен. Её использование приводит к неопределённому поведению — произойти может что угодно.

Классический пример

Возврат ссылки на локальную переменную. Локальная переменная уничтожается при возврате из функции, а вызывающий код получает ссылку на уже недействительную память.

// BUG
int& bad() {
    int x = 10;
    return x;       // x dies here
}

int& r = bad();
std::cout << r;     // UB

Ссылки на элементы контейнеров

Ссылка на элемент std::vector становится висячей, если вектор перераспределяет память. Добавление элементов может переместить всё хранилище.

std::vector<int> v = {1, 2, 3};
int& r = v[0];
v.push_back(99);    // may reallocate
std::cout << r;     // possibly UB

Ссылки на элементы отображений и списков

Некоторые контейнеры (std::list, std::map, std::unordered_map для узлов, которые не были затронуты) предоставляют стабильные итераторы и ссылки. std::vector и std::deque этого не делают.

Правила времени жизни временных объектов

Константная ссылка продлевает время жизни временного объекта, но функция, возвращающая эту ссылку, не продлевает его ещё раз.

// Subtle BUG
const std::string& f() {
    return std::string("temp"); // dies at return
}

const std::string& s = f();      // dangling

Время жизни в инструкциях if с инициализацией (C++17)

Переменные в инструкциях инициализации if/switch в C++17 живут до конца тела if/switch. Это полезно, но помните об области видимости.

if (const auto& it = map.find(k); it != map.end()) {
    use(it->second);
}
// `it` is dead here

Ссылочные члены классов

Хранение ссылки в качестве члена класса связывает время жизни класса с временем жизни объекта, на который она ссылается. Класс не может существовать дольше этого объекта. Используйте такой подход только при необходимости выразить семантику владения.

Указатель или ссылка для необязательного владения

Ссылка не может быть нулевой, но если объект, на который она ссылается, уничтожен, ссылка становится недействительной. Указатели позволяют яснее выразить необязательное владение или потенциально висячие ссылки.

Вместо этого используйте умные указатели

Для совместного владения используйте std::shared_ptr. Указатель сохраняет объект, пока существует хотя бы один shared_ptr. Это рассматривается в курсе «Умные указатели».

Помощь компилятора: lifetimebound

Современные компиляторы (Clang, GCC) выдают предупреждения для некоторых случаев висячих ссылок. Если поддерживается, включите -Wdangling-reference.

Распространённый приём: типы-представления

std::string_view и std::span — невладеющие представления. Для них действуют те же ограничения времени жизни, что и для ссылок, поэтому требуется такая же осторожность.

Быстрая проверка

Какая операция может сделать недействительными ссылки на элементы std::vector?

Итоги

Ссылки ничего не продлевают и ничем не владеют — они являются псевдонимами существующего объекта. Они становятся висячими, если объект уничтожается раньше. Остерегайтесь возврата ссылок на локальные переменные, перераспределения памяти контейнерами и сохранения ссылок на временные объекты.

Часто задаваемые вопросы

Урок «Время жизни ссылок и висячие ссылки» бесплатный?

Да — полный текст урока «Время жизни ссылок и висячие ссылки» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Время жизни ссылок и висячие ссылки»?

Избегайте висячих ссылок, внимательно анализируя время жизни объектов. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Время жизни ссылок и висячие ссылки»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужны ссылки — псевдонимы переменных
  2. Передача по значению и по ссылке
  3. Ссылки const и когда их использовать
  4. Время жизни ссылок и висячие ссылки
← Назад к C++ Academy