Mr said:
I don't understand why this crashes in the dtor of Info.
Can someone explain to me what I'm missing?
Rule of three:
If a class needs a custom destructor, it most likely also needs a
custom copy constructor and a custom assignment operator.
Your class Info falls into this category.
What is going on:
Derived(){m_SomeInfo = Info(new int(5));}
Info( new int(5))
A single int is generated (with the value 5 in it)
o------------>+------+
| 5 |
+------+
and a pointer to it is passed in the constructor of the temporary
Info object. The constructor does:
Info(int* pData):m_pData(pData)
i.e. stores this pointer
temporary Info object
+-----------+
| m_pData |
| o------------+
+-----------+ |
|
+----------+
|
+--->+------+
| 5 |
+------+
What's next? Then comes the assignment in
m_SomeInfo = Info(new int(5)
Since you didn't write an assignment operator on your own, the
compiler generated one for you, which does:
Info& Info:
perator=( const Info& Arg )
{
m_pData = Arg.m_pData;
}
That is: a memberwise assignment of all members.
Well in your case, this boils down to:
temporary Info object
+-----------+
| m_pData |
| o------------+
+-----------+ |
|
+----------+
|
+--->+------+
+--->| 5 |
| +------+
|
+--------------+
|
Derived |
+---------------------+ |
| | |
| Base | |
| +----------------+ | |
| | m_SomeInfo | | |
| | +------------+ | | |
| | | m_pData | | | |
| | | o---------------+
| | +------------+ | |
| +----------------+ |
+---------------------+
That is: The m_pData pointer in m_SomeInfo inside Base points
to the same int as the temporary Info object does.
Well. A few nanoseconds later, the temporary info object ceases to
exist. It's destructor is called, which does:
~Info(){if (m_pData) delete m_pData;}
(The if is not necessary. You can safey delete a 0 pointer).
Thus the temporary object deletes the int it has allocted just
before itself gets wiped out of memory. This leaves you with:
+--->
|
|
+--------------+
|
Derived |
+---------------------+ |
| | |
| Base | |
| +----------------+ | |
| | m_SomeInfo | | |
| | +------------+ | | |
| | | m_pData | | | |
| | | o---------------+
| | +------------+ | |
| +----------------+ |
+---------------------+
Ooops. The pointer m_pData in m_SomeInfo now points to nowhere
in memory. So when finaly that Derived object gets destroyed, all
destructors are run, especially the dtor of m_SomeInfo which tries
to delete .... hmm ... nothing sensible. There is no data anymore
where the pointer is pointing to. -> Claboom.
Google for 'Rule of three C++'
and should find enough references on how to cure this thing.