Можно ли предположить, что векторное хранилище STL всегда непрерывно? - PullRequest
55 голосов
/ 29 октября 2008

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

, например

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

Ответы [ 6 ]

72 голосов
/ 29 октября 2008

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

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

Элементы вектора хранятся смежно, что означает, что если v является вектор, где Т является некоторым типа отличного от bool, тогда он подчиняется тождество & v [n] == & v [0] + n для все 0 <= n <v.size (). </p>

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

27 голосов
/ 29 октября 2008

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

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

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

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

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

13 голосов
/ 29 октября 2008

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

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

10 голосов
/ 29 октября 2008
4 голосов
/ 29 октября 2008

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

&myVector.front();
2 голосов
/ 29 октября 2008

да.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...