Memory Leak Fixes
On this page goes fixes for memory leaks in the SDK.
Contents
KeyValues class
See KeyValues class
bin\client.dll
CPanelMetaClassMgrImp class
src\cl_dll\panelmetaclassmgr.cpp 236a237,242 CPanelMetaClassMgrImp::~CPanelMetaClassMgrImp() { > while(m_MetaClassKeyValues.Count()>0) > { > if(m_MetaClassKeyValues[0]) > m_MetaClassKeyValues[0]->deleteThis(); > m_MetaClassKeyValues.RemoveAt(0); > } }
bin\server.dll
CActBusyAnimData class
src\dlls\hl2_dll\ai_behavior_actbusy.cpp 124a125 > pKVAnimData->deleteThis(); 137c138 < pAnim->iszSequences[BA_BUSY] = pSequence ? pSequence : NULL_STRING; --- > pAnim->iszSequences[BA_BUSY] = pSequence ? AllocPooledString( pSequence ) : NULL_STRING; 139c140 < pAnim->iszSequences[BA_ENTRY] = pSequence ? pSequence : NULL_STRING; --- > pAnim->iszSequences[BA_ENTRY] = pSequence ? AllocPooledString( pSequence ) : NULL_STRING; 141c142 < pAnim->iszSequences[BA_EXIT] = pSequence ? pSequence : NULL_STRING; --- > pAnim->iszSequences[BA_EXIT] = pSequence ? AllocPooledString( pSequence ) : NULL_STRING;
WCEdit
src\dlls\wcedit.cpp 449a450,460 Vector *g_EntityPositions = NULL; QAngle *g_EntityOrientations = NULL; string_t *g_EntityClassnames = NULL; >class GlobalCleanUp : public CAutoGameSystem >{ > void Shutdown() > { > delete [] g_EntityPositions; > delete [] g_EntityOrientations; > delete [] g_EntityClassnames; > delete this; > } >}; > 459a471 if ( !g_EntityPositions ) { > new GlobalCleanUp(); g_EntityPositions = new Vector[NUM_ENT_ENTRIES]; g_EntityOrientations = new QAngle[NUM_ENT_ENTRIES]; // have to save these too because some entities change the classname on spawn (e.g. prop_physics_override, physics_prop) g_EntityClassnames = new string_t[NUM_ENT_ENTRIES]; }
Player Names
Allocated names don't get freed until LevelShutdownPostEntity.
This issue arises because of the usage of pooled strings for saving names to memory. When a name change is made, rather than deleting the old name, it just changes the netname string_t to a newly allocated string.
hl2mp_client.cpp
void ClientPutInServer( edict_t *pEdict, const char *playername ) { // Allocate a CBaseTFPlayer for pev, and call spawn CHL2MP_Player *pPlayer = CHL2MP_Player::CreatePlayer( "player", pEdict ); char trimmedName[MAX_PLAYER_NAME_LENGTH]; Q_strncpy( trimmedName, playername, sizeof( trimmedName ) ); - pPlayer->PlayerData()->netname = AllocPooledName( trimmedName ); + pPlayer->PlayerData()->netname = MAKE_STRING(strdup( trimmedName )); }
teamplay_gamerules.cpp
const char * name = engine->GetClientConVarValue( pPlayer->entindex(), "name" ); // msg everyone if someone changes their name, and it isn't the first time (changing no name to current name) // Note, not using FStrEq so that this is case sensitive if ( pPlayer->pl.netname != NULL_STRING && STRING(pPlayer->pl.netname)[0] != 0 && Q_strcmp( STRING(pPlayer->pl.netname), name ) ) { IGameEvent * event = gameeventmanager->CreateEvent( "player_changename" ); if ( event ) { event->SetInt( "userid", pPlayer->GetUserID() ); event->SetString( "oldname", STRING(pPlayer->pl.netname) ); event->SetString( "newname", name ); gameeventmanager->FireEvent( event ); } delete STRING(pPlayer->pl.netname); - pPlayer->pl.netname = AllocPooledString( name ); + pPlayer->pl.netname = MAKE_STRING(strdup( name )); }
player.cpp
CBasePlayer::~CBasePlayer( ) { VPhysicsDestroyObject(); + delete STRING(pl.netname); }
CCommentarySystem class
src\dlls\CommentarySystem.cpp [ In InitCommentary() method. Immediately after the if ( pkvFile->LoadFromFile( filesystem, szFullName, "MOD" ) ) block ] 491a492 > pkvFile->deleteThis();
CDevShotSystem class
src\dlls\point_devshot_camera.cpp [ In FrameUpdatePostEntityThink() method. Immediately after the if ( pkvMapCameras->LoadFromFile( filesystem, szFullName, "MOD" ) ) block ] 242a243 > pkvMapCameras->deleteThis();
CBasePropDoor class
src\dlls\props.cpp [ In CalcDoorSounds() method. Immediately after the if ( modelKeyValues->LoadFromBuffer( modelinfo->GetModelName( GetModel() ), modelinfo->GetModelKeyValueText( GetModel() ) ) ) block ] 3230a3231 > modelKeyValues->deleteThis();
src\lib\vgui_controls.lib
AnimationController class
src\vgui2\controls\AnimationController.cpp 1292a1293,1311 ~CPanelAnimationDictionary() { > int v2, v1 = m_AnimationMaps.Count(); > PanelAnimationMapEntry *pCur; > PanelAnimationMap *pMap; > for(int x=0;x<v1;x++) > { > pMap = m_AnimationMaps[x].map; > if(pMap) > { > v2 = pMap->entries.Count(); > for(int y=0;y<v2;y++) > { > pCur = &(pMap->entries[y]); > delete [] pCur->m_pszScriptName; > delete [] pCur->m_pszVariable; > delete [] pCur->m_pszType; > delete [] pCur->m_pszDefaultValue; > } > } > } m_PanelAnimationMapPool.Clear(); }
CBitmapImagePanel class
src\public\vgui_controls\BitmapImagePanel.h 21a22 CBitmapImagePanel( vgui::Panel *parent, char const *panelName, char const *filename = NULL ); > ~CBitmapImagePanel();
src\vgui2\controls\BitmapImagePanel.cpp 61a62,67 >CBitmapImagePanel::~CBitmapImagePanel() >{ > delete [] m_pszImageName; > delete [] m_pszColorName; >} > //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBitmapImagePanel::ComputeImagePosition(int &x, int &y, int &w, int &h)
DirectorySelectDialog class
src\vgui2\controls\DirectorySelectDialog.cpp 258c258,260 < int rootIndex = m_pDirTree->AddItem(new KeyValues("root", "Text", m_szCurrentDrive), -1); --- > KeyValues *kv = new KeyValues("root", "Text", m_szCurrentDrive); > int rootIndex = m_pDirTree->AddItem(kv, -1); > kv->deleteThis(); 294a297 m_pDirTree->AddItem(kv, parentNodeIndex); > kv->deleteThis(); } 410a414 int itemID = m_pDirTree->AddItem(kv, selectedIndex); > kv->deleteThis();
FileOpenDialog class
src\vgui2\controls\FileOpenDialog.cpp 506a507 int itemID = m_pFileTypeCombo->AddItem(filterName, kv); > kv->deleteThis(); if ( bActive )
ScrollBar class
src\vgui2\controls\ScrollBar.cpp 323c323 < _button[index]->SetParent((Panel *)NULL); --- > _button[index]->DeletePanel(); 351c351 < _slider->SetParent((Panel *)NULL); --- > _slider->DeletePanel();
Other info and links
General issues not specific to memory leaks are on the SDK Known Issues List page.