Reputation: 43427
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
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
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
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
Reputation: 22011
void reserve ( size_type n );
It only reallocates the internal array when the current capacity is less than n .
Upvotes: 0