Question

I am having problems using my custom class with a std::map. The class dynamically allocates memory for members, and I do not want to use pointer in the map because I want to ensure that the class takes care of deleting all allocated memory. But the problem I am having is after I add item to map, when that block of code goes out of scope, the objects destructor is called even though it is still on the map. I made a fake bit of code below that shows what I mean. The output is: So the problem is why is the final destructor being called? Thanks in advance and sorry for the long question.

Constructor Called Num:0034B7E8
Default Constructor Called Num:00000000
Copy Constructor Called Num:CCCCCCCC
Copy Constructor Called Num:CDCDCDCD
destructor called Num:CCCCCCCC
destructor called Num:00000000
destructor called Num:0034B7E8
Inserted Num:0034B7E8



class myClass
{
public:
  myClass(int num) 
  {
     mnNum = new int();
     cout << "Constructor Called Num:" << mnNum << endl;
   }

   myClass() : mnNum(NULL)
   {
      cout << "Default Constructor Called Num:" << mnNum << endl;
   }

   myClass(const myClass &copy) 
   {
      mnNum = new int(copy.mnNum);
      cout << "Copy Constructor Called Num:" << mnNum << endl;
   }

   ~myClass()
   {
      delete mnNum;
      mnNum = NULL;
   }

   int* mnNum;

 };

 map<string,myClass> mvMyMap;

 void testFunction()
 {
     myClass lcObj(1);

     mvMyMap["Test"] = lcObj;
 }


 int _tmain(int argc, _TCHAR* argv[])
 {
     testFunction();
     cout << "Inserted Num:" << mvMyMap["Test"].mnNum << endl;
 return 0;
  }
Was it helpful?

Solution

myClass needs a custom assignment operator, in addition to the copy constructor. So when you make an assignment, you'll leak the original value on the left, and eventually double delete the value on the right.

OTHER TIPS

Your constructor ignores the num parameter and never initializes mnNum from it. It should look like:

myClass(int num) 
{
    mnNum = new int(num);
    cout << "Constructor Called Num:" << mnNum << endl;
}

You also need to adjust your copy constructor like this:

myClass(const myClass &copy) 
{
    mnNum = new int(*copy.mnNum);
    cout << "Copy Constructor Called Num:" << mnNum << endl;
}

edit

Derek Ledbetter pointed out that we need an assignment operator, too. And I would suggest making the destructor virtual.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top