Использовать std::vector:: данные после резерва

У меня есть std::vector, на котором я называю reserve большим значением. Впоследствии я извлекаю data().

Так как итерация data затем сбой, мне интересно, разрешено ли это даже. Является ли reserve принудительно обновлять data до выделенного диапазона памяти?

Ответ 1

Гарантия reserve заключается в том, что последующие вставки не перераспределяются и, таким образом, не вызывают недействительности. Это. Больше никаких гарантий нет.

Ответ 2

Является ли reserve принудительно обновлять data до выделенного диапазона памяти?

Нет. Стандарт гарантирует, что std::vector::data возвращает указатель, а [data(), data() + size()) - допустимый диапазон, capacity не имеет значения.

$23.3.11.4/1 векторные данные [Vector.data]:

Возвращает: Указатель такой, что [data(), data() + size()) является действительным ассортимент. Для непустого вектора data() == addressof(front()).

Ответ 3

Нет требования, чтобы data() возвращал возвращаемый указатель для пустого (size() == 0) вектора, даже если он имеет ненулевую емкость. Он может возвращать nullptr или какое-либо произвольное значение (только в этом случае необходимо, чтобы он мог быть сравним с самим собой, и 0 можно было добавить к нему без вызова UB).

Ответ 4

Я бы сказал, что документация довольно понятна в этом разделе: что-нибудь после data() + size() может быть выделено, но не инициализировано: если вы хотите также инициализировать эту память, вы должны использовать vector::resize.

void reserve (size_type n);

Запросить изменение емкости

Требует, чтобы векторная емкость была по крайней мере достаточной, чтобы содержать n элементов.

Если n больше текущей емкости вектора, функция вызывает контейнер для перераспределения его хранилища, увеличивающий его емкость до n (или больше).

Во всех остальных случаях вызов функции не вызывает перераспределения и векторная емкость не изменяется.

Эта функция не влияет на размер вектора и не может изменять ее элементы.

Я не уверен, почему вы хотели бы получить доступ к чему-либо после data() + size() после reserve() в первую очередь: предполагаемое использование reserve() заключается в предотвращении ненужных перераспределений, когда вы знаете или можете оценить ожидаемый размер ваш контейнер, но в то же время избегайте ненужного начального объема памяти, который может быть либо неэффективным, либо непрактичным (например, нетривиальные данные для инициализации недоступны). В этой ситуации вы можете заменить log(N) перераспределения и копии с 1 улучшением производительности.