73

If i have in C++ a pointer to a vector:

vector<int>* vecPtr;

And i'd like to access an element of the vector, then i can do this by dereferncing the vector:

int a = (*vecPtr)[i];

but will this dereferencing actually create a copy of my vector on the stack? let's say the vector stores 10000 ints, will by dereferencing the vecPtr 10000 ints be copied?

Thanks!

BartoszKP
  • 33,416
  • 13
  • 100
  • 127
Mat
  • 10,493
  • 10
  • 42
  • 48
  • 5
    A pointer to a vector is a fairly uncommon thing - consider if you should really have a reference or a vector value. –  Dec 15 '09 at 22:12
  • 2
    It's not uncommon at all, a reference to a vector is exactly the same as a pointer to a vector as far as the generated machine code is concerned. Anyone who thinks there's any meaningful difference between pointers and references is fooling themselves. – Joe Dec 07 '17 at 13:50

2 Answers2

89

10000 ints will not be copied. Dereferencing is very cheap.

To make it clear you can rewrite

int a = (*vecPtr)[i];

as

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

In addition, if you are afraid that the whole data stored in vector will be located on the stack and you use vector<int>* instead of vector<int> to avoid this: this is not the case. Actually only a fixed amount of memory is used on the stack (about 16-20 bytes depending on the implementation), independently of the number of elements stored in the vector. The vector itself allocates memory and stores elements on the heap.

Mika Fischer
  • 3,636
  • 1
  • 23
  • 28
sergtk
  • 10,204
  • 14
  • 73
  • 127
  • 8
    Wow, I never knew that it was legal to have references as data types (vector& vecRef). I always thought this was restricted to function parameters. This is good info to have! – Amil May 13 '12 at 21:22
  • if you don't put the parentheses around the (\*vecPtr) you will get compiler error: error: no match for ‘operator*’ (operand type is ‘...... template related long text not shown – Kemin Zhou Jul 28 '17 at 18:27
  • Good to know. On the other hand `vector copied = *vecPtr;` does seem to copy the entire vector. –  Feb 05 '21 at 10:38
54

No, nothing will be copied; dereferencing just tells C++ that you want to invoke operator[] on the vector, not on your pointer, vecPtr. If you didn't dereference, C++ would try to look for an operator[] defined on the std::vector<int>* type.

This can get really confusing, since operator[] is defined for all pointer types, but it amounts to offsetting the pointer as though it pointed to an array of vector<int>. If you'd really only allocated a single vector there, then for any index other than 0, the expression evaluates to a reference to garbage, so you'll get either a segfault or something you did not expect.

In general, accessing vectors through a pointer is a pain, and the (*vecPtr)[index] syntax is awkward (but better than vecPtr->operator[](index)). Instead, you can use:

vecPtr->at(index)

This actually checks ranges, unlike operator[], so if you don't want to pay the price for checking if index is in bounds, you're stuck with (*vecPtr)[].

Todd Gamblin
  • 56,473
  • 15
  • 88
  • 96
  • 1
    Minor clarification. operator[] is defined for the std::vector*, because operator[] is defined for any pointer. But it returns no int as expected but reference to the std::vector with trash inside and which can not be assigned to int. – sergtk Dec 15 '09 at 22:27
  • Please does this apply when want to pass the vector to function that expects `const std::vector&` as a parameter? – Tomáš Zato - Reinstate Monica Jun 01 '16 at 11:30
  • is `at` as fast as accessing element by the index? – Arsen Zahray Nov 08 '20 at 19:13