What is happining in your code:
Here you are dynamically creating an object. (this is not freed in your code).
Why are you using a pointer? (Smart pointer are your friend.)
But a normal object would be preferable.
Column *c = new Column("Test");
Now you make a copy of the object as it is copied into the temporary object of type std::pair<int,Column> (This uses Column's copy constructor which makes a copy of the M_name member (you now have two pointers to the same memory location)).
std::make_pair(0, *c)
Now you insert the pair<int,Column> into the map. This is done by again using the Column copy constructor (it uses the make_pair copy constructor which calls the Column copy constructor). Again the M_name pointer is copied into this object. So now you have three objects poining at the dynamically allocated string.
m_Container->insert( pairObject )
At this point the temporary object you create with the call to std::make_pair() is no longer needed so it is destroyed. This is where you destructor is getting called. Of course this leaves you with two objects with pointer at memory that has now been released.
You have a big problem.
You either need to use std::string (preferred solution)
Or you need to correctly handle the RAW owned pointer in your class. This means you need to implement all four of the defaultly generated methods:
- constructor
- destructror
- copy constructor
- assignment operator
Small problem:
You need to stop coding like a java programmer.
Column *c = new Column("Test");
it = this->m_Container->insert(std::make_pair(0, *c)).first;
Should look like this:
m_Container[0] = Column("Test");
There is no need to dynamically allocate everything.
Infact that is very dangerious.
Explanation for why having a RAW owned pointer is a bad idea.
class X
{
char* m_name;
public:
X(char const* name) {m_name new char[strlen(m_name) +1];strcpy(m_name,name);}
~X() {delete [] m_name;}
};
This looks fine. But the compiler is also generating two methods for you. In mnost situations this is fine but not when you have a RAW owned pointer.
X::X(X const& copy)
:m_name(copy.m_name)
{}
X& X::operator=(X const& copy)
{
m_name = copy.m_name;
}
Now image the code:
X x("Martin");
X y(x);
Both 'x' and 'y' now contan pointers (m_name) pointing at the same piece of memory. When 'y' goes out of scope it calls its derstructor which calls the delete [] on the memory. Now 'x' goes out of scope and calls delete on the same piece of memory.
Z z("Bob");
z = x;
Same problem as above jsut using a different operator.
How does this apply to you?
You are using a map of pointer to Column. The map actually stores a Coloumn object. So it is using the Copy constructor above to make a copy of your object. So there is a probelm. But also in code there is a lot of times when temporary objects are created and passed around.
doWork(Column const& x) { /* Do somthing intersting */
doWork(Column("Hi There"));
Here we create a temporary Column object that is passed to the doWork(). When doWork() is complete the temporay goes out of scope and is deleted. But what happens if doWork() makes a copy of the object using either the copy costructor or assignment operator? This is what is happening when you insert the object into the map. You are creating a temporary pair then copying this value into the map. This temporarty pair is then being destroyed.