Archived

This topic is now archived and is closed to further replies.

JohanOfverstedt

Memory leaks in the win api

Recommended Posts

I am writing an application that uses the win api a lot, and I am concerned that I might be leaking memory, by not releasing something, that I should release, or some other stuff. I wonder if there are any (preferably free) programs/librarys that allow me to find out, if I am leaking memory through another library(like the win api). Thanks in advance! My game: Swift blocks

Share this post


Link to post
Share on other sites
daerid    354
Fluid Studio''s MemMgr is great for memory.

If you''re worried about leaking Win32 resources, then I''d suggest using some wrapper classes to automatically take care of the cleanup for you. A lot of those are provided using WTL or MFC (ugh).

Or, you could just turn around and use .NET WinForms.

Share this post


Link to post
Share on other sites
TempusElf    186
you probably already know this but just in case:

according to winprog.org, using SelectObject can potentially cause memory leaks if you don''t catch what it returns and get rid of it (assuming that you dont need it anymore)

for example if you''re constantly creating new brushes and only using them once you should always


bTemp = (HBRUSH)SelectObject(dcWhatever, bNewBrush);
DeleteObject(bTemp);

Share this post


Link to post
Share on other sites
daerid:

Yes, I know about that memory manager, and I use it already!
And, none of the wrapper classes seem like good options to me

TempusElf:

Thanks for that information, I actually didn''t know that
I look more at that site, to see what else I can dig up!

CheeseMonger:

Yes, something like that, is what I am looking for too.
A lib or app that tells med that!

Thanks everybody for your responses, please keep on posting advice, and maybe links and stuff

Cheers

My game: Swift blocks

Share this post


Link to post
Share on other sites
Colin Jeanne    1114
quote:
Original post by TempusElf
for example if you''re constantly creating new brushes and only using them once you should always

bTemp = (HBRUSH)SelectObject(dcWhatever, bNewBrush);
DeleteObject(bTemp);



Where did you learn this? According to the MSDN this is wrong.

quote:
MSDN on SelectObject()
An application should always replace a new object with the original, default object after it has finished drawing with the new object.





Qui fut tout, et qui ne fut rien
Invader''s Realm

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
I came across this problem today.

The correct way to avoid leaking (which doesn''t occur on Win2k,
but does on WinXP - I cannot tell about non-NT platforms) is
handling SelectObject calls like this:

HGDIOBJ old = SelectObject(dc, obj);
// use BitBlt or whatever GDI function

SelectObject(dc, old);

I think this illustrates what TempusElf said.

Share this post


Link to post
Share on other sites
TempusElf    186
quote:
Original post by Invader X

quote:
MSDN on SelectObject()
An application should always replace a new object with the original, default object after it has finished drawing with the new object.





I see what you mean but consider this:

What if I'm done with the new object, but now I want to draw with an even newer object... so I go and use SelectObject again to put the more recent object in the DC and replace the one that is there... now what happens to that one? does windows detect that I have no reference to it and get rid of it? I don't think it does (not that I'm an expert on this)

I think that you and I are talking about different situations... what I'm talking about is something like this:

HBITMAP hbmNewBitmap;
while(gameon)
{
//create a new GDI object
hbmNewBitmap = CreateCompatibleBitmap(dcSomeDC, someheight, somewidth);
//put new object into dc... replace the old
//ignoring the returned pointer to the old bitmap
SelectObject(dcSomeDC, hbmNewBitmap);
}


It seems to me that the code I just wrote is like doing this:


cFooBar fbNew;

while(gameon)
{
fbNew = new cFooBar();
}


an obvious memory leak because you aren't deallocating fbNew when you're done with it... I could be wrong...

[edited by - TempusElf on August 8, 2003 6:53:39 PM]

Share this post


Link to post
Share on other sites
I have tried the _CrtDumpMemoryLeaks but strangly never got it to work as expected.

I will try it again this night, and see if I can put some life to it!

(EDIT)
I can only get the CRT MemManager to work, when I run the application from the VC++ 6.0 IDE.

Is there a way to keep that great mem manager even when I start my app from windows explorer?
(/EDIT)

Cheers

My game: Swift blocks

[edited by - JohanOfverstedt on August 8, 2003 8:31:09 PM]

Share this post


Link to post
Share on other sites
Colin Jeanne    1114
quote:
Original post by TempusElf
quote:
Original post by Invader X

quote:
MSDN on SelectObject()
An application should always replace a new object with the original, default object after it has finished drawing with the new object.





I see what you mean but consider this:

What if I''m done with the new object, but now I want to draw with an even newer object... so I go and use SelectObject again to put the more recent object in the DC and replace the one that is there... now what happens to that one? does windows detect that I have no reference to it and get rid of it? I don''t think it does (not that I''m an expert on this)

I think that you and I are talking about different situations...


I think you and I are talking about two different things entirely. The statement from the MSDN does not pertain to what happens to the new object after you have selected it out of the DC - it only pertains to how you should clean up the DC. In the MSDN''s statement by "original" it means the first object that SelectObject() returned when you selected in the new resource - not the newer resource. When you clean up that DC you must select in the original resource first. I''m sure you understand this, I''m just reiterating the statement I am making to clear things up.

So, by using your new/newer objects example:

HBITMAP hbmNewBitmap;
while(gameon)
{
//create a new GDI object
hbmNewBitmap = CreateCompatibleBitmap(dcSomeDC, someheight, somewidth);
//put new object into dc... replace the old
//ignoring the returned pointer to the old bitmap
SelectObject(dcSomeDC, hbmNewBitmap);
}

Yes, this is a memory leak exactly like you described. And yes, Windows will not clean up the bitmaps created and then unselected during this loop. What I''m talking about is how to make sure that this leak never happens (to edit your example code):


HBITMAP hbmNewBitmap;
HBITMAP hbmOld;

...
//Create dcSomeDC

...

hbmNewBitmap = CreateCompatibleBitmap(dcSomeDC, someheight, somewidth);

hbmOld = (HBITMAP)SelectObject(dcSomeDC, hbmNewBitmap);

while(gameon)
{
//Draw and stuff

...
//Need to recreate hbmNewBitmap for whatever reason

SelectObject(dcSelectDC, hbmOld);
DeleteObject(hbmNewBitmap);
hbmNewBitmap = CreateCompatibleBitmap(dcSomeDC, someheight, somewidth);
//Modify hbmNewBitmap so that it contains the data you want

...
SelectObject(dcSomeDC, hbmNewBitmap); //We already have the original so we can ignore the return value

}

SelectObject(dcSomeDC, hbmOld);
DeleteObject(hbmNewBitmap);
...
//delete dcSomeDC after selecting the rest of the default objects



The memory leak should not occur in this code and dcSomeDC should be safe to destroy now that all default objects have been selected into it.

I guess this post is just an incredibly long-winded way of saying:

Always select the default objects back into the DC before you destroy the DC and always delete your GDI objects properly (documentation for the GDI object creation functions will explain how to delete the object correctly).



Qui fut tout, et qui ne fut rien
Invader''s Realm

Share this post


Link to post
Share on other sites
Aldacron    4544
It also possible to hook into the API and track resource allocation and deallocation yourself. There is a great example of this in a book called ''Windows Graphics Programming: Win32 GDI and DirectDraw'' by Feng Yuan. Lots of neat little tricks in that book.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Microsoft has a free tool called "AppVerifier".

Share this post


Link to post
Share on other sites
Yes, thanks a bunch, the AppVerifier sorted out a couple of problems in my app I didn''t know about!

I don''t think I will be able to buy that BoundsChecker thingy
I am just an amatuer developer yeah

Nothing I have tried yet have been able to detect even the simpliest memory leak (loading a bitmap, and not releaseing it).

I will keep on searching!

Cheers

My game: Swift blocks

Share this post


Link to post
Share on other sites
LessBread    1415
Poke around at http://www.fengyuan.com for a free utility called GDIObj. It aides in determining whether a program loses GDI resources or not.

Share this post


Link to post
Share on other sites
Thanks for the tip on that GDIOBJ program.
It seems to function pretty well!

And thanks for all the other information and tips posted here. It''s all been helpful

If anyone has any more tips or information, feel free to share it

Cheers!

My game: Swift blocks

Share this post


Link to post
Share on other sites