heya

I was coding a dll in c++, and I began getting an error inside a loop which allocates 5 dword long buffer.
At first time I used malloc(), then I tried GlobalAlloc() but an exception continued to happen.

The loop itenerations may be about 1000 or 2000, which means, about in total about 40000 bytes of memory allocation.
I think there is no problem in that...

The funny thing is that, when debugging with OllyDbg the exception doesnt occur, and the program rans fine.

Using sice, it printed some info under status window, before the exception:

"Heap missing last entry in comitted range near x"

Any idea?

thanks
Posted on 2004-01-08 18:23:15 by coder
are you doing anything in the loop except allocating memory? You should easily be able to do 2000 mallocs, even if you're allocating more than 'a few dwords'. Have you been doing anything before the loop, that might have trashed the heap structures?

Humm, you do say this is in a DLL, might change things a bit... but still, a few thousand small allocs shouldn't be a problem.

Btw, don't use Global/LocalAlloc, go HeapAlloc instead... Posted on 2004-01-08 18:45:26 by f0dder
Some vital information is missing. E.g., what exception do you get? On what platform do you develop? What is the target platform? What compiler?

Anyhow, under 9x, GlobalAlloc() is limited by the number of handles that windows reserves in the conventional DOS memory area. That is why using GlobalAlloc() for general purpose mem alloc is bad. Too many GlobalAlloc() calls will result in ENOMEM even if the physical memory is still available. In fact, ENOMEM in this case only means that the reserved handles are exhausted. In a pathological case, you could crash a win9x machine by this way. I don't know how it works under NT family. But, as f0dder said, it is not a good way.

I would stick to malloc() or HeapAlloc(). Not using malloc() might not help you to reduce the final binary size, for it is frequently used in the C/C++ start up code.
Posted on 2004-01-08 19:17:22 by Starless
If there is no exception under Ollydebug, then I would suspect an initialization error.

malloc() is not guaranteed to clear the allocated memory.

If using calloc() makes the error go away, that is a stronger case for an initialization error.

Check your pointer usage.

The sice error message says the heap has been corrupted.
Posted on 2004-01-08 20:34:06 by tenkey
uhm, what about the new[] ? Shouldn't it be better - I mean doesn't it free memory if the program crashes?
Posted on 2004-01-09 02:06:37 by Ultrano
Aren't new[] and delete[] just a wrapping? ?

I mean that C\C++ must call the o.s. to manage memory so, at the end it will call HeapAlloc() and HeapFree().

:alright:
Posted on 2004-01-09 02:48:38 by Eternal Idol Birmingham
yes, but I think they're a good wrapping - I see VC puts exception handling, but when the proggie crashes it seems the same message - I guess the SEH is put to make sure all memory taken is free. VC is a very good product, I doubt this SEH is for nothing.
Posted on 2004-01-09 04:01:54 by Ultrano
But when it puts SEH, when it tries to allocate the memory?
That should work exactly in that point, when an error arises from a HeapAlloc() call or similar.

I'm not really sure but I think that that's the way it should help, besides the calling point the application will crash without freeing memory.


:alright:


Adding : exploring the SEH MSDN documentation I've found this, 'Termination Handler'
'Unlike an exception handler, a termination handler is always executed, regardless of whether the protected block of code terminated normally. The sole purpose of the termination handler should be to ensure that resources, such as memory, handles, and files, are properly closed regardless of how a section of code finishes executing.'
Posted on 2004-01-09 04:14:58 by Eternal Idol Birmingham
Ultrano, afaik there isn't really any difference between malloc and new when dealing with simple data structures. There's no point in "freeing memory at crash", since that's done by the OS.

Where new+delete differes from malloc+free is the calling of constructors and destructors... there's still no garbage collection or automatic resource reclaiming done (though it can be added - either use some garbage collection system, or get used to some variant of smart pointers).
Posted on 2004-01-09 06:18:11 by f0dder

Some vital information is missing. E.g., what exception do you get? On what platform do you develop? What is the target platform? What compiler?

Anyhow, under 9x, GlobalAlloc() is limited by the number of handles that windows reserves in the conventional DOS memory area. That is why using GlobalAlloc() for general purpose mem alloc is bad. Too many GlobalAlloc() calls will result in ENOMEM even if the physical memory is still available. In fact, ENOMEM in this case only means that the reserved handles are exhausted. In a pathological case, you could crash a win9x machine by this way. I don't know how it works under NT family. But, as f0dder said, it is not a good way.

I would stick to malloc() or HeapAlloc(). Not using malloc() might not help you to reduce the final binary size, for it is frequently used in the C/C++ start up code.

Sorry, here it is:
Access violation exception (inside GlobalAlloc), Win2000 SP4, VS .NET 2003.

I tried to use Heap*() apis, and comented the code that writes into the buffers, ran well.
Then I changed to GlobalAlloc...and voila..also worked well...
Seems I'm playing badly with the buffer pointer ;)
I'll check it better later...school time.

Thanks for the replies.
Posted on 2004-01-09 08:51:02 by coder