Steven Lu
Steven Lu

Reputation: 43427

Does std::vector::reserve reallocate the internal array?

I have a function which takes an int * and modifies the array that is passed in. I know ahead of time how many elements it will access. Let's say that's m values.

What will happen if I call reserve(m) on a vector<int> then send the pointer data() to the function?

My guess is that doing this might work if I subsequently access the data as though it were an array, from the pointer, but if I were to try to retrieve this data from the vector using operator [] the size of the vector will not have been updated, and I will have issues. So I should just use resize(m) to do this.

Upvotes: 2

Views: 703

Answers (4)

Seth Carnegie
Seth Carnegie

Reputation: 75130

reserve changes the internal size of the container (so that capacity() is now larger) but the size of the array doesn't grow any (size() remains the same as before the call). So, to directly answer your question, yes, it makes the capacity of the vector at least n where n is the parameter you gave to reserve.

I don't know if it's undefined behaviour to access beyond the end of a vector if the capacity is large enough (but size is less) when you call data() on it (or do &v[0]) and access the array through that pointer. I don't think it would be undefined behaviour as long as you're using POD types in the vector and don't read them before you write to them. Don't try this with class types though because the elements beyond the size of a vector will be uninitialised and using them will be UB.

It would be pointless to do this though, because then when you try to push_back something on the vector or call resize to actually update the size, it will overwrite the values you subversively wrote to the vector. Just use resize or use the vector(int) constructor to set the size on construction.

Upvotes: 0

ComicSansMS
ComicSansMS

Reputation: 54589

Correct, reserve(m) on an empty vector simply guarantees that the next m push_back() will not trigger reallocation. The size of the vector will still remain 0 and writing to allocated data is forbidden.

Calling resize(m) is the correct way here.

Upvotes: 1

Kerrek SB
Kerrek SB

Reputation: 476970

Don't do it; it's undefined behaviour and simply not allowed. Instead, you should do the almost equally expensive resize() operation and then pass the data() pointer.

The only added cost comes from the zeroing out of the memory. Unfortunately there is no standard library container that handles uninitialized dynamic storage short of a std::unique_ptr<int[]>(new int[m]). The cost of the zeroing out is very small, though (but it may be conceptually annoying because you know that you are going to overwrite the data). I guess in a high-performance context you could give the unique-pointer approach a try. (Note that array-new[] for fundamental types is typically entirely equivalent to ::operator new() or malloc()).

Upvotes: 5

ApprenticeHacker
ApprenticeHacker

Reputation: 22011

void reserve ( size_type n );

It only reallocates the internal array when the current capacity is less than n .

Upvotes: 0

Related Questions