Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructor query

Tags:

c++

I have this below program, where I am passing a vector by reference to a function myFunc and inside this function, I am adding few elements to the vector.

I am not freeing object creating with new, for now ignore the memory leak due to this.

After myFunc() execution is complete I am printing the variables ctor and dtor to know how many times constructor and destructor were called.

Output is:

Before Exiting 5 7

I am creating 5 objects so ctor is 5. But why is dtor 7? From where do the extra two counts? Am I missing something?

#include
#include
using namespace std;

static int ctor = 0;
static int dtor = 0;

class MyClass
{
public:
    MyClass(int n)
    {
        i = n;
        ctor++;
        // cout << "Myclass ctor " << ctor << endl; 
    } 

    ~MyClass()
    {
        dtor++; 
        // cout << "Myclass dtor" << dtor << endl;
    }

private: 
    int i;
}; 

void myFunc(vector<MyClass> &m);

void myFunc(vector<MyClass> &m)
{
    MyClass *mc;

    for(int i = 0; i < 5; i++)
    {
        mc = new MyClass(i);
        m.push_back(*mc);
    }
}

int main()
{

    vector<MyClass> m;
    vector<MyClass>::iterator it;

    myFunc(m);

    cout << "Before Exiting " << ctor << " " << dtor << endl;
}
like image 693
irappa Avatar asked Sep 02 '11 18:09

irappa


2 Answers

Vectors copy around objects, but only your int constructor increments ctor. That's not accounting for copy constructed objects, and because you didn't provide one, the compiler provided it for you.

Add

MyClass(const MyClass& rhs) i(rhs.i) { ++ctor; }

to your class to see if that balances the count.

like image 91
Seth Carnegie Avatar answered Oct 05 '22 16:10

Seth Carnegie


Vectors start at a low size. When you push an element into them, they make a copy of it using the copy constructor so you don't see your normal constructor get called. When the vector size grows beyond its limit, it will increase its limit by a multiple of its current size (e.g. double it).

Vectors are guaranteed to always keep objects in contiguous memory, so if adding a new object exceeds the vectors capacity() (i.e. size() + 1 > capacity()), the vector allocates new memory somewhere and copies all elements into it. This will again use the copy constructor. So, your elements from the vector pre-resize will call their destructors after they are copied into the newly allocated space with their copy-constructor.

So, more destructor calls than normal constructor calls :)

like image 38
John Humphreys Avatar answered Oct 05 '22 15:10

John Humphreys