2010-03-11 2 views
3

Я только заметил, что для vector push_back это возвращает ссылку на элемент.Один вопрос о vector push_back

void push_back (const T& x); 

Мой вопрос заключается в том, что макет памяти изменился после push_back?

Например, у меня есть массив, который содержит пять элементов и макет.

|   |   |   |   |   |    
| A1  |  A2 | A3  | A4 | A5 | 

Теперь у меня есть вектор Ú

v.push_back(A3) 

Теперь, как же память выглядеть?

Как вектор хранит элементы здесь?

Как вектор получает доступ к элементу?

+0

Посмотрите на вектор :: резерв и вектор :: емкость относительно макета памяти. Имейте в виду, что, поскольку распределение памяти может измениться, любые итераторы, которые у вас были до вызова push_back, становятся недействительными после изменения содержимого вектора. –

ответ

6

Векторный магазины по стоимости не по ссылке.

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

Пример:

std::vector<std::string> v; 
string s = ""; 
v.push_back(s); 
s = "hi"; 
v.push_back(s); 

v теперь содержит 2 различных элементов, один с пустой строкой, и один со строкой, которая содержит "hi". Обе строки в векторе остаются независимыми от s.

Примечание: внутренние детали реализации контейнера STL могут отличаться, нет гарантии, что он будет реализован определенным образом; однако семантика работы контейнера STL останется неизменной независимо от внутренней реализации.

+0

'string s =" hi ";' должно быть 's =" hi ";', правильно? – fredoverflow

+0

Семантика std :: vector однако включает формат памяти, он должен находиться в непрерывной памяти с 2003 "TC1". В любом случае все реализации всегда делали это так. – jamuraa

0
| A1  |  A2 | A3  | A4 | A5 | A3  | 

Элементы (как и все в STL) хранятся по значению.

Векторы доступа к элементам, как и встроенные массивы.

3

Теперь, как выглядит память? и Как вектор хранит элементы здесь?

Есть два возможных результата:

  1. блок памяти вектора не является достаточно большим, чтобы содержать элементы, поэтому основной памяти перераспределить. Объекты копируются (используя их конструкторы копирования) в их новые местоположения. Затем объект push_back 'd копируется (по значению) до конца.
  2. Блок памяти вектора достаточно велик, новые элементы копируются (по значению) до конца.

Как вектор получает доступ к элементу?

Точно так же вы получаете доступ к массиву C-стиля. BasePointer + index

2

vector::push_back принимает ссылку, а затем считывает значение при ссылке, чтобы скопировать его в вектор.

Так что результирующий вектор будет

| A3 | 

Обратите внимание, что, когда вектор изменяется для размещения новых данных, он может перемещать старые данные в новое место, недействительностями старых ссылок на него. Таким образом, если список A1, A2, ... A5 являетсяv,

v.push_back(A3) 

аннулирует A3A3 как данные ссылки внутри v. Единственный способ сохранить дескриптор данных внутри вектора по мере его роста - сохранить индекс; ссылки, указатели и итераторы не будут делать.

+0

Нет, это не приведет к аннулированию A3, потому что это делается по значению. Результирующий вектор будет | A3 | A3 | в вашем примере. Оба объекта все еще действительны. –

+0

@Billy: Я утверждал, что A3 является ссылкой на объект внутри 'v'. Читайте ближе. – Potatoswatter

+0

Нет, OP говорит, что 'push_back' принимает ссылочный параметр, но это все. –

Смежные вопросы