diff --git a/Generals/Code/GameEngine/Include/Common/Overridable.h b/Generals/Code/GameEngine/Include/Common/Overridable.h index 30105265b27..6f782cb557f 100644 --- a/Generals/Code/GameEngine/Include/Common/Overridable.h +++ b/Generals/Code/GameEngine/Include/Common/Overridable.h @@ -105,6 +105,15 @@ class Overridable : public MemoryPoolObject { if ( m_isOverride ) { + // TheSuperHackers @bugfix Clean up the override chain before deleting this node. + // Without this, deleteInstance(this) triggers ~Overridable() which deletes m_nextOverride + // via the destructor, but the caller may still hold a pointer to the now-freed chain, + // creating a dangling pointer that causes an access violation in getFinalOverride(). + if ( m_nextOverride ) + { + m_nextOverride->deleteOverrides(); + m_nextOverride = nullptr; + } deleteInstance(this); return nullptr; } diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h b/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h index 1200927bd6d..0a47a6652cb 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Overridable.h @@ -105,6 +105,15 @@ class Overridable : public MemoryPoolObject { if ( m_isOverride ) { + // TheSuperHackers @bugfix Clean up the override chain before deleting this node. + // Without this, deleteInstance(this) triggers ~Overridable() which deletes m_nextOverride + // via the destructor, but the caller may still hold a pointer to the now-freed chain, + // creating a dangling pointer that causes an access violation in getFinalOverride(). + if ( m_nextOverride ) + { + m_nextOverride->deleteOverrides(); + m_nextOverride = nullptr; + } deleteInstance(this); return nullptr; }