Skip to content

[rcore][win32] Stop SetWindowIcon() from leaking the previous icon - #6239

Merged
raysan5 merged 3 commits into
raysan5:masterfrom
Ne0nWinds:win32-icon-leak
Oct 9, 2026
Merged

raysan5 merged 3 commits into
raysan5:masterfrom
Ne0nWinds:win32-icon-leak

Conversation

@Ne0nWinds

@Ne0nWinds Ne0nWinds commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Any icon created with CreateIconIndirect() must be deleted with DestroyIcon() when it is no longer in use; otherwise, it causes a memory leak. The current win32 backend doesn't do this, so every call to SetWindowIcon leaks a small amount of memory.

Testing

Windows has a function that returns the total number of GDI and USER objects that are currently allocated. This function can be used to easily detect memory leaks.

Simple Win32 memory leak test:

Image icon = GenImageColor(32, 32, RED);

for (int i = 0; i < 100; ++i)
{
    SetWindowIcon(icon);

    char buffer[256];
    unsigned long gdiObjectCount = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
    unsigned long userObjectCount = GetGuiResources(GetCurrentProcess(), GR_USEROBJECTS);
    printf("%lu %lu\n", gdiObjectCount, userObjectCount);
}

If you run the above code on current master, you'll see the number of win32 objects grow without bound. Every time SetWindowIcon is called, it allocates 3 GDI objects and 1 USER object. These objects don't get freed at any point.

Solution

The icon can be safely deleted when there are no longer any references to it. SetWindowIcon assigns two references to the same icon: ICON_SMALL and ICON_BIG.

Calling SendMessage with the WM_SETICON event returns the icon previously assigned to the window, which we can use to destroy it. We do this only after updating both ICON_SMALL and ICON_BIG to use the new icon.

When CloseWindow is called, the current icon handle is saved with WM_GETICON. The icon gets destroyed after the window gets destroyed, ensuring the window doesn't hold a bad reference to the icon.

Relevant Win32 docs:

@raysan5
raysan5 merged commit 84e4a2a into raysan5:master Oct 9, 2026
16 checks passed
@raysan5

raysan5 commented Oct 9, 2026

Copy link
Copy Markdown
Owner

@Ne0nWinds nice fix! thanks!

@Ne0nWinds
Ne0nWinds deleted the win32-icon-leak branch October 9, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants