Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Finding where my memory leaks are

Status
Not open for further replies.

SDowd

Programmer
Nov 11, 2005
91
US
Hey everyone,

Here's the scenario:
I joined a team of developers a few months ago to work on a number of different projects all with the same code base. The code base has been around for a few years at this point, in the hands of many different engineers, at different stages and times. I've tried to work around the memory leaks as I come to them and have tried to fix as many as I see in the code. Trying to use the memory dump of the output window for visual studio is a PITA to say the least. This project is a few different executables running in unison( a server and two different operator stations). While trying to run two of the apps and debug the third my system pretty much just throws up on its memory consumption and crashes out. It literally uses all the memory of my system, this is prior to any sort of debugging I'm trying to accomplish.

Is there a quick and dirty(hopefully cheap) way I can run through this program and find where these allocations are being made to clean some of this up?

I know a memory manger could be written and used, but A) time constraints limit this matter and B) The project is pretty huge.

Any ideas would be appreciated.

 
Valgrind is often suggested for these types of situations, but I don't know if it qualifies as cheap. Using the debug output window can be annoying, but it's not so bad when you see the file and line numbers of where the allocation occurs. Do you have it setup that way? If not, you have to add a special macro to the top of any source file that uses new.
 
I do not have it setup that way ~ never really needed the memory leak info. if you could point me in the right direction it would be great. I'm currently using VS 2005.

What is ValGrind?
 
Valgrind's website says it's for linux systems only:
"It runs on the following platforms: X86/Linux, AMD64/Linux, PPC32/Linux, PPC64/Linux."

We're running solely on windows.
Unless I misread the page, I don't know how much help it would be.
 
Put this at the top of a source file that you know has a memory leak:
Code:
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

Put it below the #includes and above the rest of the code. Then build the application and run it through the debugger. Do something you know will cause the memory leak from that file and close the application. In the output window, there should be at least one memory leak line that includes the file and line number in that file where the memory was originally allocated.

We try to put the above code in all source files and we almost never have a memory leak appear that can't be quickly traced to the specific line of code that allocated the memory (actually cleaning up properly is another matter ;-)).

I haven't used Valgrind, so I'm not sure if it is available for windows or not. I thought it was but I could easily be mistaken. Sorry about that.
 
Thanks. I'm going to try it out. I appreciate the help. I'll be back in a bit to try it out. Also, would it work the same if I created a header that included this new debug code and just include that file, or does it actually have to appear in each of the source files?
 
I added the code you provided to the top of one of my files and it throws a bunch of compiler errors:

specifically, DEBUG_NEW is an undeclared identifier. \

Am I forgetting to add something? Is there something in the project properties that needs to be set?
 
Hmm... I honestly don't know how to set it up completely. It's been years since I've done that. You'll have to search these forums or MSDN to find the full instructions. I was assuming it would work because it sounded like you already have crtDumpMemoryLeaks working.

Here's a link to get you started:
Hopefully that will work in your environment.
 
I've been looking through the MSDN and the crtDumpMemoryLeaks function. I've been trying to follow what it says, but it still doesn't provide file and line information. Even when I include crtDumpMemoryLeaks() during my system's OnExit function. still gives me the regular old:

normal block .. etc x bytes long
Data: hex values

it is getting me frustrated.

Also at the top of the MSDN page you listed, it states MFC Library Reference. Is that to assume it will only work with MFC?
 
It's possible. I haven't tried the file/line number thing with a plain windows app. Sorry I can't be of more help on that.
 
It's alright. I appreciate the effort. At least it gave me some other options to try. I'm sure I'm doing something wrong somewhere. I guess we're just going to have to deal with it for the time being. I don't feel overly bad about it.. wasn't my code.. hehe.

If anyone else could add anything to this discussion, I'm all ears [bigears]
 
When you get your leak report, look for the {nnn} allocation numbers.


Starting from the lowest numbered leaked block, set the break alloc counter to that value and re-test with exactly the same input.

Within the debugger, you can then follow that allocation back to where the program stores the result, and from then perhaps work out why it isn't being freed, and how to free it.


--
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
 
so then should i make the call to _CrtSetBreakAlloc() in my app's OnExit function? OnInit? Does it matter? Also, won't i get different allocation Ids(i don't know their actual name), the {nnn}, from one execution to another? I tried capturing one of them and giving that to _CrtSetBreakAlloc(73950}, but it gave me different allocation numbers than before. 73950 was my lowest on the first run-through, then making my call in my OnExit() to _CrtSetBreakAlloc(73950), appeared to do nothing, and the lowest number my output window dumped out was 73952. Did I do it incorrectly?
 
Try hitting F10 to start your app. Then in the watch put:
Code:
{,,msvcrtd.dll}*__p__crtBreakAlloc()
(You might have to change the dll name, this is an old instruction and I don't know if there is a newer version for 8.0.)

Then type in the number (73950 or 73952) for the value and hit enter to make sure it gets saved. Finally, hit F5 to run.

This is how I usually do it so I don't have to re-compile every time.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top