Если у меня есть в C++ указатель на вектор:
vector<int>* vecPtr;
И я хотел бы получить доступ к элементу вектора, затем я могу сделать это dereferncing вектор:
int a = (*vecPtr)[i];
но это разыменование на самом деле создаст копию моего вектора на стеке? скажем, вектор хранит 10000 ints, будет путем разыменования vecPtr 10000 ints быть скопированным?
Спасибо!
10000 int
s не будет скопировано. Разыменование очень дешево.
Для наглядности можно переписать
int a = (*vecPtr)[i];
как
vector<int>& vecRef = *vecPtr; // vector is not copied here
int a = vecRef[i];
Кроме того, если вы боитесь, что все данные, хранящиеся в векторе
, будут располагаться на стеке, и вместо вектора
вы используете вектор
, чтобы избежать этого: дело обстоит иначе.
Фактически на стеке используется только фиксированный объем памяти (около 16-20 байт в зависимости от реализации), независимо от количества элементов, хранящихся в векторе vector
.
Сам вектор вектор
выделяет память и хранит элементы на куче
Нет, ничего не будет скопировано; разыменование просто сообщает Си++, что вы хотите вызвать оператор[] на векторе -, а не на указателе -, -VecPtr
. Если бы не разыменование, Си++ попытался бы искать оператор[], определенный на типе std::vector
.
Это может ввести в заблуждение, так как operator[]
определен для всех типов указателей, но это равносильно смещению указателя, как если бы он указывал на массив из vector
. Если бы там действительно был выделен только один вектор, то для любого индекса, кроме 0
, выражение вычисляется как ссылка на мусор, и получается либо сегфальт, либо что-то, чего не ожидалось.
В общем, доступ к векторам через указатель - это боль, а синтаксис (*vecPtr)[index]
неудобен (но лучше, чем vecPtr->оператор[](index)
). Вместо этого можно использовать:
vecPtr->at(index)
Это на самом деле проверяет диапазоны, в отличие от оператора[]
, поэтому если вы не хотите платить цену за проверку того, что индекс находится в границах, то вы застряли с (*vecPtr)[]
.