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

StackOverflow https://stackoverflow.com/questions/247738

  •  05-07-2019
  •  | 
  •  

Вопрос

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

например ,

vector<char> vc(100);
// do some stuff with vc
vc.resize(200);
char* p = &vc[0];
// do stuff with *p
Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

Элементы a vector хранятся последовательно, что означает, что если 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();

ДА.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top