CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Sep 2019
    Posts
    4

    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;
    
    }

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    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

  3. #3
    Join Date
    Sep 2019
    Posts
    4

    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.

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: GDIPLUS Weird Memory Leak

    Quote Originally Posted by Capitano95 View Post
    ... 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

  5. #5
    Join Date
    Sep 2019
    Posts
    4

    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.

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: GDIPLUS Weird Memory Leak

    Quote Originally Posted by Capitano95 View Post
    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?

  7. #7
    Join Date
    Sep 2019
    Posts
    4

    Re: GDIPLUS Weird Memory Leak

    Exactly. But without any error codes. It just shuts down.

  8. #8
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: GDIPLUS Weird Memory Leak

    Run the app under a debugger so you can catch the crash.

  9. #9
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: GDIPLUS Weird Memory Leak

    Quote Originally Posted by Capitano95 View Post
    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

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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
  •  





Click Here to Expand Forum to Full Width

Featured