Можно ли предположить, что хранилище векторов STL всегда смежное?
Если у вас есть вектор STL, который был изменен, безопасно ли взять адрес элемента 0 и предположить, что остальная часть вектора будет следовать в памяти?
например.
vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
Ответы
Ответ 1
Да, это допустимое предположение (*).
Из стандарта С++ 03 (23.2.4.1):
Элементы вектора сохраняются смежно, что означает, что если v является вектор, где T - некоторый тип, отличный от bool, тогда он подчиняется идентификатор & v [n] == & v [0] + n для все 0 <= n < V.SIZE().
(*)... но следите за тем, что массив перераспределяется (аннулирование любых указателей и итераторов) после добавления к нему элементов.
Ответ 2
Стандартная добавленная С++ 03 формулировка, чтобы было ясно, что векторные элементы должны быть смежными.
С++ 03 23.2.4 Параграф 1 содержит следующий язык, который отсутствует в стандартном документе С++ 98:
Элементы a vector
сохраняются смежно, что означает, что если v
является vector<T, Allocator>
где T
некоторый тип, отличный от bool
, то он подчиняется тождеству &v[n] == &v[0] +
n
для всех 0 <= n < v.size()
.
Herb Sutter рассказывает об этом изменении в одном из своих записей в блоге, Cringe not: Векторы гарантированно будут смежными:
... Примыкание на самом деле является частью векторная абстракция. Его так важно, на самом деле, когда он был обнаружен что стандарт С++ 98 didnt полностью гарантировать соприкосновение, В стандарт С++ 03 были внесены поправки явно добавьте гарантию.
Ответ 3
Хранение всегда смежное, но оно может перемещаться по мере изменения векторной емкости.
Если перед операцией изменения емкости у вас был указатель, ссылка или итератор на нулевом элементе (или любом элементе), он недействителен и должен быть переназначен.
Ответ 4
Да, он смежный
Ответ 5
std::vector
гарантирует, что элементы хранятся в непрерывном массиве и, следовательно, являются предпочтительной заменой массивов, а также могут использоваться для взаимодействия с зависимым от платформы низкоуровневым кодом (например, вызовами Win32 API). Чтобы получить указатель на массив, используйте:
&myVector.front();
Ответ 6
да.
он всегда должен быть смежным