Указатель вектора разыменования на элемент доступа - PullRequest
48 голосов
/ 16 декабря 2009

Если у меня в C ++ указатель на вектор:

vector<int>* vecPtr;

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

int a = (*vecPtr)[i];

но создаст ли эта разыменование копию моего вектора в стеке? скажем, вектор хранит 10000 целых, будет ли путем разыменования копировать vecPtr 10000 целых?

Спасибо!

Ответы [ 2 ]

58 голосов
/ 16 декабря 2009

10000 int с копироваться не будет. Разыменование очень дешево.

Чтобы было понятно, вы можете переписать

int a = (*vecPtr)[i];

как

vector<int>& vecRef = *vecPtr; // vector is not copied here
int a = vecRef[i];

Кроме того, если вы боитесь, что все данные, хранящиеся в vector, будут расположены в стеке, и вы используете vector<int>* вместо vector<int>, чтобы избежать этого: это не так. На самом деле в стеке используется только фиксированный объем памяти (около 16-20 байт в зависимости от реализации), независимо от количества элементов, хранящихся в vector. vector сам выделяет память и сохраняет элементы в куче.

44 голосов
/ 16 декабря 2009

Нет, ничего не будет скопировано; Разыменование просто говорит C ++, что вы хотите вызвать оператор [] для вектора , а не для вашего указателя , vecPtr. Если вы не разыменовываете, C ++ попытается найти оператор [], определенный для типа std::vector<int>*.

Это может привести к путанице, поскольку operator[] определено для всех типов указателей, но это равносильно смещению указателя, как если бы он указывал на массив vector<int>. Если вы действительно выделите там только один вектор, то для любого индекса, отличного от 0, выражение оценивается как ссылка на мусор, так что вы получите либо segfault, либо что-то, чего не ожидали.

В общем, доступ к векторам через указатель является проблемой, а синтаксис (*vecPtr)[index] неудобен (но лучше, чем vecPtr->operator[](index)). Вместо этого вы можете использовать:

vecPtr->at(index)

Это фактически проверяет диапазоны, в отличие от operator[], поэтому, если вы не хотите платить цену за проверку, находится ли индекс в границах, вы застряли с (*vecPtr)[].

...