C中的野指针—如何避免 点击打开链
c++开发如何避免和解决野指针和内存泄漏问题 点击打开链接
一个简单防止野指针的方法
点击打开链接
野指针产生的原因与避免方法、调试寻找野指针的方法
点击打开链接
设计建议
比如你需要一块内存,你申请了一块内存,你不需要的时候把指针浅拷贝存到一个空闲内存容器,你下次需要使用的时候就去空闲内存容器拿内存使用。
这样好处一是减少了野指针出现,而二是避免多次new和delete,产生内存碎片。
例子:
WorldPlayer* m_WorldPlayerMap[MAX_ROLE_ID];
std::map<t_GUID,WorldPlayer*> m_PlayerMap;
std::map<string,WorldPlayer*> m_PlayerNameMap;
std::map<t_GUID,WorldPlayer*> m_WorldPlayerOffLineMap; //上过线又不在线的玩家容器
//玩家上线登录
TBool NetDBCache::ServicePlayerFirstEnterScene( tagNetMsg& msg,WorldPlayer* pPlayer )
{
WorldPlayer * pWorldPlayer = gWorldPlayerMgr.GetFirstOffLinePlayer(); //获得离线玩家内存
if(pWorldPlayer == NULL)
pWorldPlayer = new WorldPlayer(); //申请新内存
if(pWorldPlayer == NULL )
return false;
}
WorldPlayer* WorldPlayerMgr::GetFirstOffLinePlayer()
{
if (m_WorldPlayerOffLineMap.size() > 0)
{
map<t_GUID,WorldPlayer*>::const_iterator it = m_WorldPlayerOffLineMap.begin();
WorldPlayer* pWorldPlayer = it->second;
m_WorldPlayerOffLineMap.erase(it);
return pWorldPlayer;
}
return NULL;
}
TBool WorldPlayerMgr::AddPlayer(WorldPlayer *pWorldPlayer)
{
if(pWorldPlayer == NULL)
{
//Log::Instance()->WriteLog(enLogType_Error, "玩家指针为空,");
return false;
}
t_RoleID nRoleID = pWorldPlayer->GetRoleID();
if(!IsValidPlayerRoleId(nRoleID))
{
//Log::Instance()->WriteLog(enLogType_Error, "AddPlayer玩家RoleId不合法,RoleId[%d]",nRoleID);
return false;
}
WorldPlayer *pPlayer = m_WorldPlayerMap[nRoleID];
if(pPlayer)
{
//Log::Instance()->WriteLog(enLogType_Warning, "重复登录,RoleId[%d]",nRoleID);
return false;
}
t_GUID nPlayerGUIID = pWorldPlayer->GetGUID();
m_WorldPlayerMap[nRoleID] = pWorldPlayer;
m_PlayerMap[nPlayerGUIID] = pWorldPlayer;
m_PlayerNameMap[pWorldPlayer->GetRoleName()] = pWorldPlayer;
return true;
}
//并没有释放他的内存,可以覆盖数据继续使用
TBool WorldPlayerMgr::DelPlayer(t_RoleID nPlayerID)
{
if(!IsValidPlayerRoleId(nPlayerID))
{
//Log::Instance()->WriteLog(enLogType_Error, "DelPlayer玩家RoleId不合法,RoleId[%d]",nPlayerID);
return false;
}
WorldPlayer *pPlayer = m_WorldPlayerMap[nPlayerID];
if(pPlayer == NULL)
{
return false;
//Log::Instance()->WriteLog(enLogType_Error, "下线玩家不存在,RoleId[%d]",nPlayerID);
}
t_GUID nPlayerGUIID = pPlayer->GetGUID();
string RoleName = pPlayer->GetRoleName();
m_WorldPlayerOffLineMap[nPlayerGUIID] = pPlayer; //离线玩家列表
m_WorldPlayerMap[nPlayerID] = NULL;
m_PlayerNameMap.erase(RoleName);
map<t_GUID,WorldPlayer*>::iterator itr = m_PlayerMap.find( nPlayerGUIID );
if(itr != m_PlayerMap.end())
m_PlayerMap.erase(itr);
return true;
}