Skip to content

Update CreateColorProfileFromLogColorSpace to steer people away from a memory leak #2025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: docs
Choose a base branch
from

Conversation

rickbrew
Copy link
Contributor

@rickbrew rickbrew commented Jun 1, 2025

The documentation indicates that you should use GlobalFree on the value stored at the address given by pProfile.

In other words,

BYTE* pProfile = NULL;
CreateProfileFromLogColorSpaceW(..., &pProfile);
GlobalFree((HGLOBAL)pProfile);

This is wrong, it is a memory leak. If you do this 65,536 times in a row then this method will start returning ERROR_NOT_ENOUGH_MEMORY. Apparently that's the maximum number of HGLOBALs you can have.

The correct pattern is this:

BYTE* pProfile = NULL;
CreateProfileFromLogColorSpaceW(..., &pProfile);
HGLOBAL hProfile = GlobalHandle(pProfile);
GlobalFree(hProfile);

I ran into this issue while working on my desktop app. I had a bug in a caching layer that was causing my color profile caching to not work, so it was recreating the profile on every call into the cache. After using the app for a few minutes it would crash because I convert Win32 errors into .NET exceptions.

cc @Sergio0694

…om memory leak

The documentation indicates that you should use `GlobalFree` on the value stored at the address given by `pProfile`.

In other words, 

```c
BYTE* pProfile = NULL;
CreateProfileFromLogColorSpaceW(..., &pProfile);
GlobalFree((HGLOBAL)pProfile);
```

This is wrong, it is a memory leak. If you do this 65,536 times in a row then this method will start returning `ERROR_NOT_ENOUGH_MEMORY`. Apparently that's the maximum number of `HGLOBAL`s you can have.

The correct pattern is this:

```c
BYTE* pProfile = NULL;
CreateProfileFromLogColorSpaceW(..., &pProfile);
HGLOBAL hProfile = GlobalHandle(pProfile);
GlobalFree(hProfile);
```

I ran into this issue while working on my desktop app. I had a bug in a caching layer that was causing my color profile caching to not work, so it was recreating the profile on every call into the cache. After using the app for a few minutes it would crash because I convert Win32 errors into .NET exceptions.

cc @Sergio0694
Copy link

@rickbrew : Thanks for your contribution! The author(s) and reviewer(s) have been notified to review your proposed change.

@rickbrew rickbrew changed the title Update CreateColorProfileFromLogColorSpaceW to steer people away from a memory leak Update CreateColorProfileFromLogColorSpace to steer people away from a memory leak Jun 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants