Выбор ответа Senior Указатели и ссылки спрашивают часто обновлено

Ссылка на элемент вектора после push_back

Вопрос

Вектор заполнен до ёмкости: v.size() == v.capacity(). Взяли int& r = v[0];, затем выполнили v.push_back(42); r = 1;. Что происходит?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: UB: pushback перевыделил память, r указывает в освобождённый буфер. При size() == capacity() вставка обязана выделить новый буфер и перенести элементы, после чего все ссылки, указатели и итераторы на старые элементы недействительны.

Варианты ответа

  1. v[0] станет 1: ссылка следует за элементом при перевыделении
  2. UB: push_back перевыделил память, r указывает в освобождённый буферправильный ответ
  3. Ошибка компиляции: нельзя брать неконстантную ссылку на элемент вектора
  4. Исключение std::out_of_range: вектор проверяет недействительные ссылки

Разбор

При size() == capacity() вставка обязана выделить новый буфер и перенести элементы, после чего все ссылки, указатели и итераторы на старые элементы недействительны. Запись через r пишет в освобождённую память.

  • v[0] не изменится: новый элемент лежит по другому адресу.
  • Брать ссылку на элемент можно, опасно хранить её через изменения вектора.
  • Никаких исключений: проверок нет, это UB (AddressSanitizer покажет heap-use-after-free).

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме