Можно ли предположить, что векторное хранилище STL всегда является непрерывным?
если у вас есть вектор STL, который был изменен, безопасно ли взять адрес элемента 0 и предположить, что остальная часть вектора будет следовать в памяти?
например
vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
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();