The short answer is that the entire array holding the vector's data is moved around to a location where it has space to grow. The vector class reserves a larger array than is technically required to hold the number of elements in the vector. For example:
vector< int > vec;
for( int i = 0; i < 100; i++ )
vec.push_back( i );
cout << vec.size(); // prints "100"
cout << vec.capacity(); // prints some value greater than or equal to 100
The capacity()
method returns the size of the array that the vector has reserved, while the size()
method returns the number of elements in the array which are actually in use. capacity()
will always return a number larger than or equal to size()
. You can change the size of the backing array by using the reserve()
method:
vec.reserve( 400 );
cout << vec.capacity(); // returns "400"
Note that size()
, capacity()
, reserve()
, and all related methods refer to individual instances of the type that the vector is holding. For example, if vec
's type parameter T is a struct that takes 10
bytes of memory, then vec.capacity()
returning 400
means that the vector actually has 4000
bytes of memory reserved (400 x 10 = 4000
).
So what happens if more elements are added to the vector than it has capacity for? In that case, the vector allocates a new backing array (generally twice the size of the old array), copies the old array to the new array, and then frees the old array. In pseudo-code:
if(capacity() < size() + items_added)
{
size_t sz = capacity();
while(sz < size() + items_added)
sz*=2;
T* new_data = new T[sz];
for( int i = 0; i < size(); i++ )
new_data[ i ] = old_data[ i ];
delete[] old_data;
old_data = new_data;
}
So the entire data store is moved to a new location in memory that has enough space to store the current data plus a number of new elements. Some vectors may also dynamically decrease the size of their backing array if they have far more space allocated than is actually required.