bool CPythonNonPlayer::LoadNonPlayerData(const char *c_szFileName)
{
DWORD dwElements;
TMobTable *pTable = (TMobTable *) zObj.GetBuffer();
for(DWORD i = 0; i < dwElements; ++i, ++pTable)
{
TMobTable *pNonPlayerData = new TMobTable;
memcpy(pNonPlayerData, pTable, sizeof(TMobTable));
m_NonPlayerDataMap.insert(TNonPlayerDataMap::value_type(pNonPlayerData->dwVnum, pNonPlayerData));
}
return true;
}
我的问题是:我做错了什么?这会泄漏很多内存。每次调用此函数后,应用程序使用量都会增加10MB。
答案 0 :(得分:3)
问题不在此功能中。问题在于您处理m_NonPlayerDataMap
的方式。此功能将某些对象的所有权转移到该地图,并且当它完成时,它将delete
的责任映射到它们。我打赌它没有。
顺便说一句,要避免这种问题,就是不要这样做。除非你真的需要,否则不要使用new
。相反,使地图成为值的地图,而不是指针地图。如果你无法找到实现这一目标的任何方法,至少使用智能指针而不是原始指针。
答案 1 :(得分:1)
使用智能指针包装器为您处理内存管理,例如:
如果使用的是早于C ++ 11的版本:
#include <memory>
// std::auto_ptr is not container-safe!
typedef std::map<DWORD, TMobTable*> TNonPlayerDataMap;
TNonPlayerDataMap m_NonPlayerDataMap;
...
bool CPythonNonPlayer::LoadNonPlayerData(const char *c_szFileName)
{
DWORD dwElements = ...;
...
// I'm assuming this just returns a pointer to an existing memory
// buffer and is not actually allocating a new buffer. If it is,
// you need to free it when you are done copying it...
//
TMobTable *pTable = (TMobTable *) zObj.GetBuffer();
for(DWORD i = 0; i < dwElements; ++i, ++pTable)
{
std::auto_ptr<TMobTable> pNonPlayerData(new TMobTable);
// don't use memcpy! better would be to give TMobTable a copy constructor instead...
// std::auto_ptr<TMobTable> pNonPlayerData(new TMobTable(*pTable));
//
*pNonPlayerData = *pTable;
// if successful, release local ownership of the object.
// if failed, ownership will remain here and free the object when the auto_ptr goes out of scope.
//
if (m_NonPlayerDataMap.insert(std::make_pair(pNonPlayerData->dwVnum, pNonPlayerData.get())).second)
pNonPlayerData.release();
}
return true;
}
或者,如果您使用的是C ++ 11或更高版本:
#include <memory>
// std::unique_ptr is container-safe!
typedef std::map<DWORD, std::unique_ptr<TMobTable>> TNonPlayerDataMap;
TNonPlayerDataMap m_NonPlayerDataMap;
...
bool CPythonNonPlayer::LoadNonPlayerData(const char *c_szFileName)
{
DWORD dwElements = ...;
...
// I'm assuming this just returns a pointer to an existing memory
// buffer and is not actually allocating a new buffer. If it is,
// you need to free it when you are done copying it...
//
TMobTable *pTable = (TMobTable *) zObj.GetBuffer();
for(DWORD i = 0; i < dwElements; ++i, ++pTable)
{
std::unique_ptr<TMobTable> pNonPlayerData(new TMobTable);
//
// or, if using C++14 or later:
// std::unique_ptr<TMobTable> pNonPlayerData = std::make_unique<TMobTable>();
// don't use memcpy! better would be to give TMobTable a copy constructor instead...
// std::unique_ptr<TMobTable> pNonPlayerData(new TMobTable(*pTable));
// std::unique_ptr<TMobTable> pNonPlayerData = std::make_unique<TMobTable>(*pTable);
//
*pNonPlayerData = *pTable;
// if successful, ownership of the object is transferred into the map.
// if failed, ownership will remain here and free the object when the unique_ptr goes out of scope.
//
m_NonPlayerDataMap.insert(std::make_pair(pNonPlayerData->dwVnum, std::move(pNonPlayerData)));
}
return true;
}