Hi! While porting this project to Android (fadi-labib/Generals-Android — built directly on your iOS port, thank you, it made a <24h port possible), Bionic's dirty malloc unmasked several latent bugs that exist on all platforms — desktop/iOS get away with them only because their allocators happen to hand back zeroed pages at those call sites.
1. Pathfinder::Pathfinder() never initializes m_blockOfMapCells (Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp)
reset() — called from the constructor — does delete [] m_blockOfMapCells before nulling it. If the freshly allocated object's memory isn't zero, that's a delete[] on a garbage pointer during GameEngine::init. Fix: add m_blockOfMapCells(nullptr) to the ctor init list.
2. W3DBridgeBuffer::W3DBridgeBuffer() calls clearAllBridges() with m_numBridges uninitialized (GeneralsMD/.../W3DBridgeBuffer.cpp)
clearAllBridges() loops [0, m_numBridges) doing REF_PTR_RELEASE on each entry — with garbage m_numBridges that's an out-of-bounds release loop. Fix: m_numBridges = 0; before the call.
3. W3DSmudgeManager constructor is empty (Core/GameEngineDevice/.../W3DSmudge.cpp)
ReleaseResources() then runs REF_PTR_RELEASE on garbage m_backgroundTexture/m_indexBuffer. Fix: zero-init all members.
4. DX8Wrapper::_Get_DX8_Back_Buffer leaves bb uninitialized, and DXVK can return D3D_OK with *ppBackBuffer == nullptr (Core/.../dx8wrapper.cpp)
When the swapchain has no back buffer yet, a garbage stack pointer gets wrapped as a "valid" surface. Fix: IDirect3DSurface8 *bb = nullptr; plus a null-check in W3DSmudgeManager::ReAcquireResources (degrade the heat-haze effect instead of crashing).
All four are fixed and device-verified in 2b7bb0020 — the commit message carries the full root-cause writeups. Happy to open a PR against your main if you'd like them; they're deliberately tiny and platform-neutral. (Android additionally routes global new through calloc because this 2003 codebase pervasively assumes zeroed allocations — that part is Android-guarded and not proposed here.)
Hi! While porting this project to Android (fadi-labib/Generals-Android — built directly on your iOS port, thank you, it made a <24h port possible), Bionic's dirty
mallocunmasked several latent bugs that exist on all platforms — desktop/iOS get away with them only because their allocators happen to hand back zeroed pages at those call sites.1.
Pathfinder::Pathfinder()never initializesm_blockOfMapCells(Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp)reset()— called from the constructor — doesdelete [] m_blockOfMapCellsbefore nulling it. If the freshly allocated object's memory isn't zero, that's adelete[]on a garbage pointer duringGameEngine::init. Fix: addm_blockOfMapCells(nullptr)to the ctor init list.2.
W3DBridgeBuffer::W3DBridgeBuffer()callsclearAllBridges()withm_numBridgesuninitialized (GeneralsMD/.../W3DBridgeBuffer.cpp)clearAllBridges()loops[0, m_numBridges)doingREF_PTR_RELEASEon each entry — with garbagem_numBridgesthat's an out-of-bounds release loop. Fix:m_numBridges = 0;before the call.3.
W3DSmudgeManagerconstructor is empty (Core/GameEngineDevice/.../W3DSmudge.cpp)ReleaseResources()then runsREF_PTR_RELEASEon garbagem_backgroundTexture/m_indexBuffer. Fix: zero-init all members.4.
DX8Wrapper::_Get_DX8_Back_Bufferleavesbbuninitialized, and DXVK can returnD3D_OKwith*ppBackBuffer == nullptr(Core/.../dx8wrapper.cpp)When the swapchain has no back buffer yet, a garbage stack pointer gets wrapped as a "valid" surface. Fix:
IDirect3DSurface8 *bb = nullptr;plus a null-check inW3DSmudgeManager::ReAcquireResources(degrade the heat-haze effect instead of crashing).All four are fixed and device-verified in
2b7bb0020— the commit message carries the full root-cause writeups. Happy to open a PR against your main if you'd like them; they're deliberately tiny and platform-neutral. (Android additionally routes globalnewthroughcallocbecause this 2003 codebase pervasively assumes zeroed allocations — that part is Android-guarded and not proposed here.)