Можно ли предположить, что векторное хранилище STL всегда является непрерывным?


если у вас есть вектор STL, который был изменен, безопасно ли взять адрес элемента 0 и предположить, что остальная часть вектора будет следовать в памяти?

например

vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
6 55

6 ответов:

Да, это правильное предположение (*).

из стандарта C++03 (23.2.4.1):

элементы вектора хранятся непрерывно, это означает, что если V является вектор, где T некоторая тип bool, и тогда он подчиняется идентичность &v[n] = = &v[0] + n для все 0

(*)... но следите за тем, чтобы массив был перераспределен (аннулируя любые указатели и итераторы) после добавления элементов оно.

стандарт C++03 добавил формулировку, чтобы было ясно, что векторные элементы должны быть смежными.

C++03 23.2.4 пункт 1 содержит следующий язык, который не в стандартном документе C++98:

элементы a несколько смежно, что означает, что если v это vector<T, Allocator> здесь T - это некоторые типа bool, потом он подчиняется личности &v[n] == &v[0] + n для всех 0 <= n < v.size().

Херб Саттер говорит об этом изменении в одной из своих записей в блоге, съежиться не: векторы гарантированно будут смежными:

... смежность на самом деле является частью векторная абстракция. Это так важно, на самом деле, когда это было обнаружено что стандарт C++98 не полностью гарантировать примыкания, Стандарт C++03 был изменен на явно добавьте гарантию.

хранение всегда непрерывное, но оно может двигаться по мере изменения емкости вектора.

Если у вас был указатель, ссылка или итератор на нулевом элементе (или любом элементе) перед операцией изменения емкости, он недействителен и должен быть переназначен.

std::vector гарантирует, что элементы хранятся в непрерывном массиве и поэтому являются предпочтительной заменой массивов, а также могут использоваться для взаимодействия с зависящим от платформы низкоуровневым кодом (например, вызовы Win32 API). Чтобы получить указатель на массив используйте:

&myVector.front();

да.

Он всегда должен быть смежным