Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why successive vector::push_back results into different number of constructor call?

class base
{
    private:
            int k;
    public:
            base(const base& b){ this->k = b.k; cout<<"  c-ctor "<<endl; }
            base(int a = 10){ k = a; }

            ~base(){cout << "destructor called\n";}
};

int main()
{
    base b, b1(2);
    vector<base> m;
    cout << "first pushback" <<endl;
    m.push_back(b);
    cout << "2nd pushback" <<endl;
    m.push_back(b1);
    cout << "3rd pushback" <<endl;
    m.push_back(b1);
    cout << "4th pushback" <<endl;
    m.push_back(b);
    cout << "5th pushback" <<endl;
    m.push_back(b);
    cout<<" =============================================== "<<endl;

    return 0;
}

Outputs:

first pushback
  c-ctor 
2nd pushback
  c-ctor 
  c-ctor 
destructor called
3rd pushback
  c-ctor 
  c-ctor 
  c-ctor 
destructor called
destructor called
4th pushback
  c-ctor    
5th pushback
  c-ctor 
  c-ctor 
  c-ctor 
  c-ctor 
  c-ctor 
destructor called
destructor called
destructor called
destructor called
 =============================================== 

destructor called
destructor called
destructor called
destructor called
destructor called
destructor called
destructor called

Why ith push_back leading to i number of copy constructor calls?

Isn't it a resizing effect( i.e. copying the original vector again) and rather inefficient way of inserting elements into a vector?

Why 4th push_back is having different behavior than 2th, 3th abd 5th push_back?

Demo

like image 499
Saurav Sahu Avatar asked Dec 15 '16 10:12

Saurav Sahu


People also ask

What does the std::vector Push_back () method do?

vector::push_back() push_back() function is used to push elements into a vector from the back. The new value is inserted into the vector at the end, after the current last element and the container size is increased by 1.

How vector works What's the complexity of the Push_back?

push_back is amortized O(1) time complexity. There is normally extra space and no extra work, the item is inserted in one iteration. When extra space is required, there may be an O(N) copy loop, not O(N^2).

Does Push_back increase size of vector?

push_back effectively increases the vector size by one, which causes a reallocation of the internal allocated storage if the vector size was equal to the vector capacity before the call.

Does std::vector Push_back make a copy?

Yes, std::vector<T>::push_back() creates a copy of the argument and stores it in the vector. If you want to store pointers to objects in your vector, create a std::vector<whatever*> instead of std::vector<whatever> .


1 Answers

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.

  1. Before 1st push_back, capacity is 1. So it does not need to be re-allocated.
  2. 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 for push_back. Capacity is now 2.
  3. Third push_back again needs to reallocate the vector because capacity is now 2. After reallocation capacity becomes 4.
  4. Now no reallocation happens, so just one call to copy ctor (for push_back). Capacity is still 4.
  5. 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.

like image 53
nishantsingh Avatar answered Sep 28 '22 20:09

nishantsingh