Click here to Skip to main content
15,881,876 members
Articles / Programming Languages / C++
Article

Report on a possible memory leak in LoadImage(..)

Rate me:
Please Sign up or sign in to vote.
1.17/5 (16 votes)
2 Aug 20035 min read 102.4K   311   26   19
LoadImage may leak memory
Run this program several times in Windows 98:

Attempt to create a deliberate memory leak using LoadImage(...)
This message then occurs when you try to start Explorer or other programs - and persists after you exit from the program.that loaded the cursors.

Out of Memory error message after running the program a few times
You then have to reboot Windows to continue

Introduction

LoadImage is the routine used to load images, bitmaps and cursors. The help for this routine says that it cleans up resources on exit, but is a bit vague in what it says about memory. Normally Windows cleans up memory too on exit, but in some circumstances it seems that it fails to do so for LoadImage.

The observations may have other explanations. What you have to do is to first load a huge number of cursors using LoadImage. When you try to start another program you get out of memory messages, or access violations or GDI errors - so far this is not so suprising perhaps. However, the messages persist after you exit from the app that caused them in the first place. The only solution then is to reboot to continue working.

Background

The help for LoadImage says: The system automatically deletes these resources when the process that created them terminates, however, calling the appropriate function saves memory and decreases the size of the process's working set. (My emphasis).

What does saves memory mean here? I haven't found any information about the cause for it anywhere, though on-line searches bring up a few pages with comments by coders who have found this leak and developed work arounds for it. The situations that make the leak noticeable are fairly rare but not that unusual - for instance if you accidentally leave out the LR_SHARED flag and load a cursor repeatedly, then your app will not only run out of memory for the cursors eventually, but when it does so the user will be forced to reboot to continue

The memory leak isn't detected by standard memory leak detectors such as the one built in to MSVC.

Using the code

Here is the code that causes the memory leak:

C++
// Create a memory leak deliberately using LoadImage(..)
for (i = 0; i < 50000; i++)
{
    hCursor = (HCURSOR) LoadImage(hInstance, "cursor1", 
                                  IMAGE_CURSOR, 0, 0,
                                  LR_DEFAULTSIZE); // don't use LR_SHARED 
                                                   // here

    if(!hCursor)
        break;

// DestroyCursor(hCursor); // leave this out to cause the leak
}

You may need to wait a little while for all the cursors to load. Run this program. You may well get out of memory errors of course if you then try to run another program while this one is running. However, exit from it and then see if they persist. If not, try running it maybe half a dozen times. If you still get no errors after it has exited then probably your setup doesn't have this problem.

This happens in Win 98 and I'm told it also happens in Win 2K.

I also tried the test with bitmaps.

C++
for (i = 0; i < 50000; i++)
{
    HBITMAP hBitmap = (HBITMAP) LoadImage(hInstance, "10MB_BITMAP", 
                                          IMAGE_BITMAP, 0, 0, 0);

    if (!hBitmap)
        break;

// DestroyObject(hBitmap);
}

No memory leak error messages occurred after exiting from this program in Windows 98. I ran the test program several times. However I understand it can cause leaks in Windows ME. I hope other members will respond to this article with details for the other operating systems.

Points of Interest

The first important point is to make sure you use LR_SHARED for cursors and icons where it is possible (this flag can only be used for standard size resources, can't be used if you load the resource from a file, and can't be used for bitmaps since they are not of a fixed standard size).

The best solution is to keep handles for all the cursors you load and destroy them explicitly when your program exits, and ditto for icons and images. The observations so far (though not conclusive) seem to suggest that if you can't use the LR_SHARED flag you should always destroy these resources explicitly if your program is likely to be used in Windows 98 or Win 2K.

Although the problem showed up in a situation where a bug caused a program to load thousands of copies of a cursor (once for every frame of an animation), I don't know whether or not it will also occur if you load just a single cursor or a few custom cursors. Does the use of LR_SHARED prevent the leak? If it does then fine, as most uses of the routine will set the flag LR_SHARED. But if not, then since nearly all Windows programs rely on automatic freeing of custom cursors on exit, then it means that nearly every time you run a program with custom cursors in Windows 98 or 2K, you are leaking a few hundred bytes of memory, maybe even a few KB if it has a fair number of them! In the case of a computer that is on 24/7 for months, that would add up eventually.

Also the out of memory message happens after you load maybe 5,000 or so cursors at 326 bytes each - but if it is indeed a memory issue one would expect to need to load millions of cursors before one notices anything, at least if one has several hundred megabytes of RAM installed. There I can think of two possibilities so far - that it is a memory fragmentation issue, so that many small allocations are worse - or that it is really some kind of resource issue getting reported as a memory allocation problem in the error messages from Windows.

Another interesting note - in Windows 98 SysMon shows the memory as freed when you exit from the program even though the out of memory messages persist at that point. Does this mean it is a resource issue, or is it because the memory is still allocated but for some reason not reported in the system monitor? The observation that it also happens in Win 2K suggest it might be a memory issue rather than a resource issue.

If anyone has any information about this or further observations, please share it with the rest of us. Thanks!

History

First release.

Related article

Check for and free memory leaks

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United Kingdom United Kingdom
Trained as a mathematician.

Now I program shareware apps - music and 3D. Main ones so far, Fractal Tune Smithy (music) and Virtual Flower (3D / VRML).

Comments and Discussions

 
GeneralMy vote of 1 Pin
Gyl9-Jul-09 22:35
Gyl9-Jul-09 22:35 
GeneralMy vote of 2 Pin
Niklas L15-Apr-09 0:54
Niklas L15-Apr-09 0:54 
The reasons for this behaviour should have been explored further.
GeneralLoadImage BUG Pin
Reza Aghazadeh8-Apr-06 20:27
Reza Aghazadeh8-Apr-06 20:27 
GeneralProcess GDI Handle Limit is around 12000 Pin
Oskar Wieland6-Aug-03 9:15
Oskar Wieland6-Aug-03 9:15 
GeneralRe: Process GDI Handle Limit is around 12000 Pin
Emmo10-Aug-03 13:12
Emmo10-Aug-03 13:12 
GeneralYou have to clean-up yourself, same as CImageList Pin
darthmaul5-Aug-03 1:05
darthmaul5-Aug-03 1:05 
GeneralI'm not sure I see the point... Pin
Ryan Binns3-Aug-03 15:04
Ryan Binns3-Aug-03 15:04 
GeneralRe: I'm not sure I see the point... Pin
Robert Inventor3-Aug-03 15:24
Robert Inventor3-Aug-03 15:24 
GeneralRe: I'm not sure I see the point... Pin
converdb5-Dec-03 12:48
converdb5-Dec-03 12:48 
GeneralRe: I'm not sure I see the point... Pin
Anonymous5-Dec-03 16:49
Anonymous5-Dec-03 16:49 
GeneralMay be this is just me... Pin
Brian Shifrin3-Aug-03 11:59
Brian Shifrin3-Aug-03 11:59 
GeneralRe: May be this is just me... Pin
Robert Inventor3-Aug-03 13:01
Robert Inventor3-Aug-03 13:01 
GeneralRe: May be this is just me... Pin
Steve Mayfield3-Aug-03 13:51
Steve Mayfield3-Aug-03 13:51 
GeneralRe: May be this is just me... Pin
Robert Inventor3-Aug-03 14:03
Robert Inventor3-Aug-03 14:03 
GeneralRe: May be this is just me... Pin
Brian Shifrin3-Aug-03 16:47
Brian Shifrin3-Aug-03 16:47 
GeneralRe: May be this is just me... Pin
Robert Inventor4-Aug-03 15:08
Robert Inventor4-Aug-03 15:08 
GeneralRe: May be this is just me... Pin
Uli Grepel5-Aug-03 22:58
Uli Grepel5-Aug-03 22:58 
GeneralRe: May be this is just me... Pin
Brian Shifrin10-Aug-03 3:11
Brian Shifrin10-Aug-03 3:11 
GeneralRe: May be this is just me... Pin
dcolwell4-Aug-03 19:42
dcolwell4-Aug-03 19:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.