Reputation: 331
So, I've got the following Command Pattern implementation, which is contained within a std::map<CString, IWrite*> commandMap
:
class IWrite
{
protected:
CStdioFile* fileWriter;
public:
IWrite(CStdioFile* _fileWriter)
: fileWriter(_fileWriter)
{
}
virtual ~IWrite()
{
}
virtual BOOL exec() = 0;
};
class FloatWrite : public IWrite
{
private:
float input;
public:
FloatWrite(CStdioFile* _fileWriter, float _input)
: IWrite(_fileWriter), input(_input)
{
}
BOOL exec()
{
CString fieldvalue;
fieldvalue.Format("%f", input);
fileWriter->WriteString(fieldvalue);
return TRUE;
}
};
The issue I'm having is that my static analysis tool complains that fileWriter
is not freed or zeroed in the destructor of IWrite
. However, by adding a delete fileWriter
in the destructor, I get a memory access error when I delete the Command Pattern object in the map before calling std::map.clear()
as below:
// free map memory
for ( std::map<CString, IWrite*>::iterator mapItr = commandMap.begin();
mapItr != commandMap.end();
++mapItr)
{
delete mapItr->second;
}
commandMap.clear();
Am I approaching memory management incorrectly here? I have not done much work with STL maps, so I'm not familiar with an idiomatic approach.
EDIT: How I add elements to the map:
void FooClass::initCommandMap(const MSG_DATA_STRUCT * msgdata)
{
// Write a float, foo
commandMap[_T("foo")] = new FloatWrite(&fileWriter, msgdata->foo);
// Write an unsigned int, bar
commandMap[_T("bar")] = new UIntWrite(&fileWriter, msgdata->bar);
// etc...
}
This is called each time the user chooses to write out the data, so the fileWriter
object used by the various exec()
's is current with the file selected by the user.
Note that CStdioFile fileWriter
is a member variable of FooClass
.
Upvotes: 1
Views: 254
Reputation:
Why do you keep a pointer to fileWriter? From what I see, your Command object assumes that a writer should exist before the command can be used. It also shouldn't try to manage the writer object, since it can be shared by multiple command objects. Try keeping a reference instead.
class IWrite
{
protected:
CStdioFile &fileWriter;
public:
IWrite(CStdioFile &_fileWriter)
: fileWriter(_fileWriter)
{
}
virtual ~IWrite()
{
}
virtual BOOL exec() = 0;
};
Upvotes: 1