-
September 3rd, 2019, 02:29 AM
#1
GDIPLUS Weird Memory Leak
Hello Guys,
i need help with some code of mine. I am using GDIPlus and am trying to create a Get Pixel Function. My Function works fine, but unfortunately i get some weird memory issues. My GDI-Object counter in task manager increases, but I dont know why. Especially since it is not a big increase, but a small one, like 2 GDI Objects in 5 minutes eventhough i call the function multiple times per second. I added the function down here.
Best regards, thanks for the help!
Code:
INT GetColor(INT iX, INT iY, HWND WinHandle) {
int value = 0;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
RECT rect;
int WindowWidth;
int WindowHeight;
if (GetWindowRect(WinHandle, &rect))
{
WindowWidth = rect.right - rect.left;
WindowHeight = rect.bottom - rect.top;
}
HDC hDDC = GetDC(WinHandle);
HDC hCDC = CreateCompatibleDC(hDDC);
HBITMAP hBMP = CreateCompatibleBitmap(hDDC, WindowWidth, WindowHeight);
SelectObject(hCDC, hBMP);
BitBlt(hCDC, 0, 0, WindowWidth, WindowHeight, hDDC, 0, 0, SRCCOPY);
Gdiplus::Bitmap *BMP = new Gdiplus::Bitmap(hBMP, NULL);
Gdiplus::Color PixelColor;
BMP->GetPixel(iX, iY, &PixelColor);
Value = PixelColor.GetValue();
ReleaseDC(WinHandle, hDDC);
DeleteDC(hDDC);
DeleteDC(hCDC);
DeleteObject(hBMP);
delete BMP;
DeleteObject(BMP);
Gdiplus::GdiplusShutdown(gdiplusToken);
return Value;
}
-
September 3rd, 2019, 03:51 AM
#2
Re: GDIPLUS Weird Memory Leak
1. These two lines
Code:
delete BMP;
DeleteObject(BMP);
The order must be changed:
Code:
DeleteObject(BMP);
delete BMP;
2. Why do you create BMP in the heap rather than stack?
3. Please read the docs carefully to correctly use all these GDI functions:
DeleteDC function
ReleaseDC function
DeleteObject function
Last edited by VictorN; September 3rd, 2019 at 08:30 AM.
Reason: spellchecking
Victor Nijegorodov
-
September 3rd, 2019, 04:39 AM
#3
Re: GDIPLUS Weird Memory Leak
Thank you very much for your help! I changed Nr.1 and read the suggestions in Nr. 3 and will test them. Maybe this already fixed the problem. Unfortunately i do not completely understand what you mean with Nr. 2. Would you be so kind and elaborate on that? Thank you very much! Kind regards!
Last edited by Capitano95; September 3rd, 2019 at 07:12 AM.
-
September 3rd, 2019, 08:36 AM
#4
Re: GDIPLUS Weird Memory Leak
Originally Posted by Capitano95
... Unfortunately i do not completely understand what you mean with Nr. 2. Would you be so kind and elaborate on that? Thank you very much! Kind regards!
Your code:
Code:
Gdiplus::Bitmap *BMP = new Gdiplus::Bitmap(hBMP, NULL);
Gdiplus::Color PixelColor;
BMP->GetPixel(iX, iY, &PixelColor);
However, you could write it so:
Code:
Gdiplus::Bitmap BMP (hBMP, NULL);
Gdiplus::Color PixelColor;
BMP.GetPixel(iX, iY, &PixelColor);
and then you would not delete anything!
Victor Nijegorodov
-
September 3rd, 2019, 09:04 AM
#5
Re: GDIPLUS Weird Memory Leak
I tried it that way, but my application just closes if i do it like that. That is why i found the other way.
-
September 6th, 2019, 03:49 AM
#6
Re: GDIPLUS Weird Memory Leak
Originally Posted by Capitano95
I tried it that way, but my application just closes if i do it like that. That is why i found the other way.
By closing, do you mean crashing?
-
September 6th, 2019, 02:56 PM
#7
Re: GDIPLUS Weird Memory Leak
Exactly. But without any error codes. It just shuts down.
-
September 6th, 2019, 09:36 PM
#8
Re: GDIPLUS Weird Memory Leak
Run the app under a debugger so you can catch the crash.
-
September 7th, 2019, 01:23 AM
#9
Re: GDIPLUS Weird Memory Leak
Originally Posted by Capitano95
Exactly. But without any error codes. It just shuts down.
But there is no any error checking in the code snippet you have posted!
Victor Nijegorodov
-
September 7th, 2019, 05:14 AM
#10
Re: GDIPLUS Weird Memory Leak
A problem is here:
Code:
RECT rect;
int WindowWidth;
int WindowHeight;
if (GetWindowRect(WinHandle, &rect))
{
WindowWidth = rect.right - rect.left;
WindowHeight = rect.bottom - rect.top;
}
If GetWindowRect() fails with a return value of false, then values are not assigned to WindowsWidth & WindowHeight and as these haven't been previously assigned, then their values will be unknown. A better C++17 way to code this could be :
Code:
int WindowWidth = 0;
int WindowHeight = 0;
if (RECT rect; GetWindowRect(WinHandle, &rect))
{
WindowWidth = rect.right - rect.left;
WindowHeight = rect.bottom - rect.top;
} else {
Gdiplus::GdiplusShutdown(gdiplusToken);
return 0; //Return an error code of some value
}
Ideally, this would go before the call to GdiplusStartup(), so that in the event of a GetWindowRect() failure, you wouldn't then need to shutdown gdiplus.
Not withstanding Victor's comments in posts #2 & #4,
Code:
delete BMP;
DeleteObject(BMP);
is incorrect because BMP is a pointer to memory for an object, not the object itself. This should be:
Code:
DeleteObject(*BMP);
delete BMP;
Also, as Victor pointed out in post #9, apart from the check for GetWindowRect(), there is no other error checking in the code! You should check the return value from every API call to make sure that the API hasn't returned an error code. Also in your function GetColor(), there is no provison to indicate to its caller that an error occurred!
Last edited by 2kaud; September 7th, 2019 at 05:17 AM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|