views:

296

answers:

3

From a previous question about vector capacity, Mr. Bailey said:

In current C++ you are guaranteed that no reallocation occurs after a call to reserve until an insertion would take the size beyond the value of the previous call to reserve. Before a call to reserve, or after a call to reserve when the size is between the value of the previous call to reserve and the capacity the implementation is allowed to reallocate early if it so chooses.

So, if I understand correctly, in order to assure that no reallocation happens until capacity is exceeded, I must do reserve twice? Can you please clarify it?

I am using vector as a memory stack like this:

std::vector<double> memory;
memory.reserve(size);
memory.insert(memory.end(), matrix.data().begin(), matrix.data().end()); // smaller than size
memory.resize(memory.capacity(), 0);

I need to guarantee that reallocation does not happen in the above.

thank you.

ps: I would also like to know if there is a better way to manage memory stack in similar manner other than vector

A: 

It reallocates when it needs more. You don't need to reserve twice. It is a good idea to use reserve if you're doing a lot of inserting and you have good knowledge of the size of what you're storing. It's much faster.

Jay
+3  A: 

I think you're reading the statement wrong. Reserve is allowed to set capacity to a larger amount than what you reserved. The special language is to allow an implementation to reallocate if you're reserving more than you did the last time, but before you've reached the current capacity.

Mark Ransom
okay, thank you.I am not English speaker and that sentence was somewhat confusing to me
aaa
@Mark, I don't find this entry to be very clear. 23.3.6.2.2 of C++0X FCD is clearer: Effects: A directive that informs a vector of a planned change in size, so that it can manage the storageallocation accordingly. After reserve(), capacity() is greater or equal to the argument of reserve ifreallocation happens; and equal to the previous value of capacity() otherwise. Reallocation happensat this point if and only if the current capacity is less than the argument of reserve(). If an exceptionis thrown other than by the move constructor of a non-CopyConstructible type, there are no effects.
Nathan Ernst
A: 

You shouldn't need to call reserve twice.

Additionally, in the code sample posted, you've only called reserve once. In actuality the code you're pasting affects the size of the vector. See 23.3.6.2.11 (C++0x FCD) on effects of void resize(size_type sz, const T& c);:

if (sz > size())
    insert(end(), sz-size(), c);
else if (sz < size())
    erase(begin()+sz, end());
else
     ; // do nothing

So, basically, when you call memory.resize(memory.capacity(), 0), you are, in effect, appending on 0, memory.capacity() - memory.size() times following your call to memory.insert.

Nathan Ernst
that is intent.I require some zero memory
aaa