简体   繁体   中英

Memory Management with Command Pattern

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 .

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;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM