I've an App that takes about 4 hours to run before it throws the error
I'm trying to fix, so I don't really fancy single-stepping it. It's
throwing me a user break point in _heap_alloc_dbg at
if (lRequest == _crtBreakAlloc) _CrtDbgBreak();
I guess this is an "out of heap memory" error. The App basically builds
lots of models, tests them and then kicks the results out to a text
file, so I'm creating and destroying a lot of objects, which is why I
think I've a memory leak.
The break actually comes during a call to CArray::SetSize, although I
do appreciate that this could be a red herring (especially as the
parameters are 2 and -1). However, in terms of dynamic memory
allocation, that's about all that I do. I've no "new" calls and no
CObLists. I've a load of CArrays and some CLists, but that's about it.
Just before I call SetSize(), I've called RemoveAll() so
(theoretically) the memory should have been freed up here. I'm also
assuming that the destructor for my class will call the destructor for
the CArray, so again the memory should be free.
Any ideas of what to try next? Are my assumptions OK? From those of you
who've debugged things like this before, am I looking in the right
place?
All help gratefully received
Paul.
eg if you have a CTypedPtrList you have to do something like
while ( ! list.Empty())
delete list.RemoveHead();
You may or may not have a memory "leak". A memory "leak" is when you allocate n objects
but free n-1 (the extreme case being when n == 1). But you can also be the victim of
"memory fragmentation", which is what happens when memory gets split up into smaller and
smaller unusable blocks until you have massive amounts of space but no particular piece is
large enough to satisfy your request. Unfortunately, this is a SERIOUSLY hard problem to
deal with. A program that runs four hours could be a victim of either problem.
One way to handle this is to force low resource situations so the problem comes up sooner.
For example, I once (on a smaller machine) did
for(i = 0; i < 10000; i++)
malloc(10000);
(Yes, it leaked like crazy, but what happened was we found the place where the test for
valid memory actually wasn't made, so the program took an access fault instead of doing
graceful recovery). The App Verifier from Microsoft (search for it on the Microsoft Web
site) would be another possibility.
The key thing here is that if you actually have a leak, by glomming all that memory at the
start you effectively eliminate many hours of running, and you can study the memory leaks
in a smaller context, perhaps running in a few minutes, if you glom enough of the heap
(actually, the 10000 in i < 10000 was a parameter I could set from, well, in those days
the command line; today I'd have a debug dialog that did it for me...)
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
On Thu, 01 Jun 2006 05:33:20 +1000, Ian Semmel <isemme...@NOKUNKrocketcomp.com.au>
wrote:
What is the value of lRequest at this moment?
Also make sure that you do not hit this problem:
http://support.microsoft.com/kb/839136/
Regards,
Oleg
[VC++ MVP http://www.debuginfo.com/]
I'm wondering if calling SetSize(0) and FreeExtra() in my destructors
will be any use?
Paul.
I looked at the KB article (thanks for this). I've downloaded SP6
(which fixes it) a while ago, but I'm not sure if I installed it - how
can I check?
I meant, what is the numeric value of lRequest? (Or _crtBreakAlloc,
which is the same, since they are equal)
If it is equal to 0xFFFFFFFF, you most likely see the problem
described in the KB article. If it is not, we should look for another
reason.
> I looked at the KB article (thanks for this). I've downloaded SP6
> (which fixes it) a while ago, but I'm not sure if I installed it - how
> can I check?
>
In general, as described here:
http://support.microsoft.com/default.aspx?scid=kb;EN-US;194295
But in this particular case, a simpler way is to set _lRequestCurr variable
to a large value (e.g. 0xFFFFFFF5) at the app's startup (use the debugger's
Watch window to set the value), and let the app run. If it soon breaks
with lRequest equal to 0xFFFFFFFF, SP6 is not installed.
Oleg
Sorry, misunderstood you - it is 0xFFFFFFFF. I have installed (or
possibly re-installed) SP6, re-built the project and lRequest has not
changed. I will set another run going tonight and see what it gives me.
Thanks for your help.
Paul.
I've installed SP6 and the program halts at exactly the same place,
with lRequest == _crtBreakAlloc == -1 (or 0xffffffff). It would appear
that I've still got the problem that Oleg pointed out, but that the fix
MS prescribe hasn't worked. I also tried the test that Oleg suggested
and, sure enough, it hits the buffers very quickly.
Should I re-install SP6? Is a move to release mode unavoidable (this is
a research project and I like having the debugging stuff there)?
I'm very very stumped and could do with some more help, please....
Paul.
Drew
"Paul S. Ganney" <paul....@hey.nhs.uk> wrote in message
news:1149587346....@u72g2000cwu.googlegroups.com...
I've checked what SP6 does, and it looks like it does not fix this problem.
So the simplest option is to switch to using release libraries (as Drew already
pointed out, release build can be debuggable just fine, if optimizations
are disabled and debug information generation enabled).
Also it should be possible to patch the place in the code where the breakpoint
exception is raised (looking at the disassembly of the function where it happens,
it should be enough to replace 'int 3' instruction (0xCC) with 'nop' (0x90)).
Oleg
Many thanks again.
Paul.