diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index bb76a273ed6..0412da5c1e6 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -1050,6 +1050,43 @@ GlobalData::~GlobalData( void ) TheWritableGlobalData = nullptr; } + // TheSuperHackers @fix Explicitly clear all AsciiString members and vectors before the automatic member + // destructors run. This ensures AsciiString::releaseBuffer() is called while the memory infrastructure + // (TheDynamicMemoryAllocator, TheAsciiStringCriticalSection) is still valid, avoiding use-after-free + // crashes that can occur when GlobalData override instances are destroyed during gameplay or shutdown. + m_simulateReplays.clear(); + m_standardPublicBones.clear(); + m_mapName.clear(); + m_moveHintName.clear(); + for (Int i = 0; i < MAX_WATER_GRID_SETTINGS; ++i) + m_vertexWaterAvailableMaps[i].clear(); + m_levelGainAnimationName.clear(); + m_getHealedAnimationName.clear(); + m_autoFireParticleSmallPrefix.clear(); + m_autoFireParticleSmallSystem.clear(); + m_autoFireParticleMediumPrefix.clear(); + m_autoFireParticleMediumSystem.clear(); + m_autoFireParticleLargePrefix.clear(); + m_autoFireParticleLargeSystem.clear(); + m_autoSmokeParticleSmallPrefix.clear(); + m_autoSmokeParticleSmallSystem.clear(); + m_autoSmokeParticleMediumPrefix.clear(); + m_autoSmokeParticleMediumSystem.clear(); + m_autoSmokeParticleLargePrefix.clear(); + m_autoSmokeParticleLargeSystem.clear(); + m_autoAflameParticlePrefix.clear(); + m_autoAflameParticleSystem.clear(); + m_shellMapName.clear(); + m_initialFile.clear(); + m_pendingFile.clear(); + m_specialPowerViewObjectName.clear(); + m_modDir.clear(); + m_modBIG.clear(); +#if defined(RTS_DEBUG) + m_baseStatsDir.clear(); + m_MOTDPath.clear(); +#endif + } //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 46d1e2f34cb..300b639bbdc 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -1095,6 +1095,43 @@ GlobalData::~GlobalData( void ) TheWritableGlobalData = nullptr; } + // TheSuperHackers @fix Explicitly clear all AsciiString members and vectors before the automatic member + // destructors run. This ensures AsciiString::releaseBuffer() is called while the memory infrastructure + // (TheDynamicMemoryAllocator, TheAsciiStringCriticalSection) is still valid, avoiding use-after-free + // crashes that can occur when GlobalData override instances are destroyed during gameplay or shutdown. + m_simulateReplays.clear(); + m_standardPublicBones.clear(); + m_mapName.clear(); + m_moveHintName.clear(); + for (Int i = 0; i < MAX_WATER_GRID_SETTINGS; ++i) + m_vertexWaterAvailableMaps[i].clear(); + m_levelGainAnimationName.clear(); + m_getHealedAnimationName.clear(); + m_autoFireParticleSmallPrefix.clear(); + m_autoFireParticleSmallSystem.clear(); + m_autoFireParticleMediumPrefix.clear(); + m_autoFireParticleMediumSystem.clear(); + m_autoFireParticleLargePrefix.clear(); + m_autoFireParticleLargeSystem.clear(); + m_autoSmokeParticleSmallPrefix.clear(); + m_autoSmokeParticleSmallSystem.clear(); + m_autoSmokeParticleMediumPrefix.clear(); + m_autoSmokeParticleMediumSystem.clear(); + m_autoSmokeParticleLargePrefix.clear(); + m_autoSmokeParticleLargeSystem.clear(); + m_autoAflameParticlePrefix.clear(); + m_autoAflameParticleSystem.clear(); + m_shellMapName.clear(); + m_initialFile.clear(); + m_pendingFile.clear(); + m_specialPowerViewObjectName.clear(); + m_modDir.clear(); + m_modBIG.clear(); +#if defined(RTS_DEBUG) + m_baseStatsDir.clear(); + m_MOTDPath.clear(); +#endif + } //-------------------------------------------------------------------------------------------------