vector push_back calling copy_constructor more than once?
What happens:
x
is inserted viapush_back
. One copy occurs: The newly created element is initialized with the argument.my_int
is taken over as zero becausex
s default constructor initialized it so.The second element is
push_back
'd; The vector needs to reallocate the memory since the internal capacity was reached.
As no move constructor is implicitly defined forMyint
1 the copy constructor is chosen; The first element is copied into the newly allocated memory (itsmy_int
is still zero... so the copy constructor showsmy_int
as0
again) and thenx
is copied to initialize the second element (as with the first in step 1.). This timex
hasmy_int
set to one and that's what the output of the copy constructor tells us.
So the total amount of calls is three. This might vary from one implementation to another as the initial capacity might be different. However, two calls are be the minimum.
You can reduce the amount of copies by, in advance, reserving more memory - i.e. higher the vectors capacity so the reallocation becomes unnecessary:
myints.reserve(2); // Now two elements can be inserted without reallocation.
Furthermore you can elide the copies when inserting as follows:
myints.emplace_back(0);
This "emplaces" a new element - emplace_back
is a variadic template and can therefore take an arbitrary amount of arguments which it then forwards - without copies or moves - to the elements constructor.
1 Because there is a user-declared copy constructor.
push_back to std::vector, the copy constructor is repeatedly called
First of all you have to remember that unless you reserve memory for the vector, it needs to allocate and reallocate memory as its capacity needs to increase.
The reallocation basically allocates new memory, then copies the element in the vector to the new memory.
Furthermore, when you push a value into a vector, that value needs to be copied into the vector. You can avoid that by emplacing the value (which means it's constructed in place in the vector), or by moving the value when you push it back.
Why successive vector::push_back results into different number of constructor call?
Not a big deal. vectors are reallocated everytime its size
reaches its capacity
. All the elements are copied from old vector to new vector.
Generally, twice the original capacity is allocated for new vector.
- Before 1st
push_back
, capacity is 1. So it does not need to be re-allocated. - For 2nd
push_back
, capacity needs to double, so two calls to copy constructor are made, first to copy old element to new vector and second forpush_back
. Capacity is now 2. - Third
push_back
again needs to reallocate the vector because capacity is now 2. After reallocation capacity becomes 4. - Now no reallocation happens, so just one call to copy ctor (for
push_back
). Capacity is still 4. - For 5th
push_back
, reallocation happens and 4 old elements and one new element (push_back
) are copied to the new vector. Capacity is now 8.
If you go ahead further, you'll observe that reallocation will happen on 9th push_back
.
Also, destructors need to be called while reallocation, when the older vector is no longer needed and hence the members in it should be destroyed.
Copy constructor get called more than one time
This is because the push_back
in your example has to do a reallocation every time. If you reserve
the size in advance then you see only one copy.
std::vector<A> vec;
vec.reserve(10);
Related Topics
How to Add a Timed Delay to a C++ Program
When and How to Use Exception Handling
Std::Shared_Ptr Thread Safety Explained
Static Variables in an Inlined Function
Difference Between C++03 Throw() Specifier C++11 Noexcept
How to Use Standard Library (Stl) Classes in My Dll Interface or Abi
How Can a C++ Header File Include Implementation
Initialize Parent's Protected Members with Initialization List (C++)
Simple Object Detection Using Opencv and MAChine Learning
When and How to Use Gcc's Stack Protection Feature
C++ Double Address Operator? (&&)
Char!=(Signed Char), Char!=(Unsigned Char)