Skip to content

fix(memory): Fix memory leak for RecorderClass::m_crcInfo#2713

Open
Caball009 wants to merge 8 commits into
TheSuperHackers:mainfrom
Caball009:fix_memory_leak_crcInfo
Open

fix(memory): Fix memory leak for RecorderClass::m_crcInfo#2713
Caball009 wants to merge 8 commits into
TheSuperHackers:mainfrom
Caball009:fix_memory_leak_crcInfo

Conversation

@Caball009
Copy link
Copy Markdown

@Caball009 Caball009 commented May 14, 2026

This PR fixes a memory leak for RecorderClass::m_crcInfo. I decided to fix this one by not allocating the CRCInfo object dynamically. This did require a larger change of moving the class to the header, though.

See commits for clean diffs.

TODO:

  • Replicate in Generals.

@Caball009 Caball009 added Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour Memory Is memory related Fix Is fixing something, but is not user facing labels May 14, 2026
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 14, 2026

Greptile Summary

This PR fixes a memory leak where RecorderClass::m_crcInfo was heap-allocated via NEW but never freed. The fix changes the member from a raw pointer to a value member, relying on automatic lifetime management.

  • CRCInfo is promoted from a file-local class in Recorder.cpp to a nested protected class of RecorderClass inside the header, enabling the value-member approach without exposing it to unrelated TUs.
  • All pointer-style accesses (->) are updated to value-style (.), and the NEW CRCInfo(...) allocation in playbackFile() is replaced with copy-assignment from a temporary, correctly reinitializing the queue between replays.
  • The same fix is applied symmetrically to both Generals/ and GeneralsMD/.

Confidence Score: 5/5

Safe to merge — the change is a straightforward heap-to-value refactor with no logic modifications.

The conversion from a raw pointer to a value member is mechanically correct throughout: the default constructor initializes the object to a sensible zero state, playbackFile() re-assigns the member via copy-assignment before any replay-related methods are called, and reset() indirectly obtains correct behavior since the next playbackFile() always reinitializes the member. All accessor call-sites are updated consistently across both Generals/ and GeneralsMD/ trees.

No files require special attention.

Important Files Changed

Filename Overview
Generals/Code/GameEngine/Include/Common/Recorder.h Promotes CRCInfo to nested class of RecorderClass; changes m_crcInfo from CRCInfo* to CRCInfo value member; adds default constructor declaration.
Generals/Code/GameEngine/Source/Common/Recorder.cpp Adds default constructor for CRCInfo; moves CRCInfo implementation to RecorderClass::CRCInfo scope; removes file-local class definition; converts all pointer accesses to value accesses; replaces NEW with copy-assignment.
GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Mirror of Generals header change — same CRCInfo nesting and value-member conversion.
GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp Mirror of Generals source change — same constructor additions, class removal, and pointer-to-value conversion for m_crcInfo.

Reviews (5): Last reviewed commit: "Tweaked 'CRCInfo' TSH comment." | Re-trigger Greptile

@Caball009 Caball009 force-pushed the fix_memory_leak_crcInfo branch from 282478b to c5e3079 Compare May 14, 2026 19:54
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
This avoids an unnecessary dynamic memory allocation and fixes a memory leak.
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Comment thread GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Copy link
Copy Markdown

@xezon xezon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. Needs replicate to Generals.

Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
// compare those with the local gamestate, they wouldn't sync up.
// So, in order to fix this, we need to queue up our local CRCs,
// so that we can check it with the crc messages that come later.
// This class is basically that queue.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While at it, perhaps compact the format of the massive comment a bit.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I did not mean to rewrite it shorter, just compacting the format of the sentences to save a bit space.

Copy link
Copy Markdown
Author

@Caball009 Caball009 May 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. You want the original comment back?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked Chat Gippy to rewrite this more densely and it wrote this:

// CRC overview:
// Each peer periodically computes a CRC from its local game state and broadcasts it to all peers, including itself,
// to verify synchronization. CRC messages are received a few frames later in network games to avoid stalling every
// frame while  waiting for all peers. This works because all peers compare the same received CRCs on the same frame.
//
// Replays are different: recorded CRC messages appear on the frame they were originally received,  so directly
// comparing them against the current local state would mismatch. To handle this, local CRCs must be queued until the
// corresponding replay CRC messages arrive. This class implements that queue.

Maybe that also works?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Comment thread GeneralsMD/Code/GameEngine/Source/Common/Recorder.cpp
Comment thread GeneralsMD/Code/GameEngine/Include/Common/Recorder.h Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Fix Is fixing something, but is not user facing Gen Relates to Generals Memory Is memory related Minor Severity: Minor < Major < Critical < Blocker ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants