Introduction
As a beginner a STL, I had lots memory leak problems to deal with, and struggled to figure out what the problems were. There problems happen in the case of trying to use the STL container to manage the pointer only. At the beginning I thought that I did put the ojbects in the container, it turned out that I just put the addresses of my ojbects in.
Truely STL will take care of everything only we do the right thing I think. To the novice of STL like me, the problem is I didn't realize that I was just letting the container to manage the poniters only.
The lession tells me that if we just put the addresses in the container, then it is our responsibility to free the memory which are requested for the objects before losing the addresses information.
Usually the bedugger would inform the leak kindly, assuming Visual Studio is used. It must be that just the addresses were deleted not actually releasing the memory.
<br>For example,we are creating a object class capsulated with stl container vector:
Example code:
Below is the code doing the "wrong thing"?
typedef std::vector<CObject *> ObjectVector;
class CObjectVector : public CObject
{
DECLARE_SERIAL(CObjectVector);
public:
CObjectVector();
public:
public:
public:
public:
virtual void Serialize(CArchive& ar);
public:
void RemoveObject(int nIndex);
void RemoveAll();
void AddObject(CObject object);
virtual ~CObjectVector();
private:
ObjectVector m_ObjectVector;
private:
};
CObjectVector::CObjectVector(){
}
CObjectVector::~CObjectVector(){
m_ObjectVector.clear();
}
void CObjectVector::RemoveAll(){
m_ObjectVector.clear();
}
void CObjectVector::RemoveObject(int nIndex){
Vector<CObject*>::iterator where = m_ObjectVector[nIndex];
m_ObjectVector.erase(where);
}
void CObjectVector::AddObject(CObject* object){
m_ObjectVector.push_back(object);
}
void CObjectVector::Serialize(CArchive& ar){
if (ar.IsStoring())
{
for(i=0;i<m_ObjectVector.size();i++){
ar << m_ObjectVector[i];
}
}
else
{
RemoveAll();
CObject* object;
for(i=0;i<m_nWordsCount;i++){
ar >> object;
AddObject(object));
}
}
Now, below code trys to the right thing:
<PRE>
CObjectVector::~CObjectVector(){
for(int i=0;i<m_ObjectVector.size();i++)
delete m_ObjectVector[i];
m_ObjectVector.clear();
}<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"> </P><P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">
void CObjectVector::RemoveAll(){
for(int i=0;i<m_ObjectVector.size();i++)
delete m_ObjectVector[i];
m_ObjectVector.clear();
}</P><P class=MsoNormal style="MARGIN: 0cm 0cm 0pt">
void CObjectVector::RemoveObject(int nIndex){
delete m_ObjectVector[nIndex];
Vector<CObject*>::iterator where = m_ObjectVector[nIndex];
m_ObjectVector.erase(where);
}</P>
That is all, and the other containers(list,map,etc) will have the same situation when you let them manage the pointer/address only.
Just remeber to delete elements (mean delete the actual object) first from the container classes before using operation such as erase(), clear() because these operation might just delete the poniters.
Good luck!
Acknowledgement
Thank you, Rolf! Thanks for pointing out some big mistakes