2016-08-16 2 views
12

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

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

+3

Почему 'reserve', а не' resize'? 'reserve' только выделяет в нем объекты памяти,' resize'. –

+4

Можем ли мы увидеть ваш код? – wasthishelpful

+2

@ n.m Изменение размера может быть настолько дорогостоящим. Резерв гарантирует, что вы сможете заменить объекты позже. –

ответ

14

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

3

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

10

Действительно ли reserve был вынужден обновить data в выделенном диапазоне памяти?

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

§23.3.11.4/1 vector data [vector.data]:

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

1

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

void reserve (size_type n);

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

Просит, чтобы вектор емкость быть достаточно, чтобы содержать минимум п элементов.

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

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

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

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