Link to home
Start Free TrialLog in
Avatar of nils pipenbrinck
nils pipenbrinck

asked on

LocalAlloc/LocalFree

Hi. I'm working on a small project, where I have to code without the standard libaries.. Thus I have no heap (and I'm to lazy to write one myself).

I used the LocalAlloc and LocalFree functions for memory management so far.. I just wonder if there are any restrictions (maximum of allocated handles or so) I should be aware of.

At the moment everything works fine.

and btw... isn't it strange, that the winapi has a malloc/free function? Why the hell do they did that?
ASKER CERTIFIED SOLUTION
Avatar of jhance
jhance

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jhance
jhance

BTW, the number of HANDLES you can use _IS_ limited under Win9x but not under NT.  On Win9x, handles fall into the System Resources category and will consume that resource.  They're not very big, however, so you can have many thousands of them in practice.  If it's a problem, all you need to do is grab a big block from Windows with one handle and then parcel it out yourself.  But then you're writing your own heap manager and you said you didn't want to do that.
The best function should be VirtualAlloc (and VirtualFree). It doesn't consume any handles and has some extra functionality (like reserving but not yet allocating - COOL)...

Regards, Madshi.
>> Under Win32 the LocalAlloc, GlobalAlloc,
>> malloc, and C++ new are all basically going
>> to the same source of memory,
That is not completely true.   LocalAlloc() and GlobalAlloc() allocate from the windows heap.  malloc() and new allocate from the C++ RTL heap.  This is an important difference.  The windows OS heap and C+++ heap were designed for different purposes and work under different circumstances.  The OS heap needs top allocate memory for whole proceses so it was designed to perform a realtively small number of very large allocations.  The C++ heap needs to allocate memory in a range of sizes (including many small allcoations) and often has to perform a huge number of allcoations.  

>> malloc are new are provided for compatibility
>> with the C and C++ runtime libraries.  They are
>> both "wrappers" around the GlobalAlloc function
>> to make it act right.
malloc could be written to use GlobalAlloc(), but that would be costly as it would clog up the OS heap.  Most impliemtnations have malloc allocate out of a heap that is private to the process.  (The heap memory itself is allocated using Globalalloc(), then the heap is managed by the C/C++ RTL or by the windows API heap functions.)

>> all you need to do is grab a big block from
>> Windows with one handle and then parcel it
>> out yourself.  But then you're writing your
>> own heap manager and you said you didn't
>> want to do that.
Windows provides the functions you need to do that.  Allocate tte heap memory with GlobaAlloc().  Then use HeapCreate() to convert it to a heap and use HeapAlloc() to allocate from this heap.

>> The best function should be VirtualAlloc (and VirtualFree).
Best in what sense?  Again that is very costly.  You wouldn't want to use it for all allocations, just ones that need those features.
nils pipenbrinck,
If you have to do only a small number of allocations, then you can continue to use GlobalAlloc(), but if you need to perform many allocations (and if need to allcoate and free very frequently), you should create your own heap as I suggested, this lessens the load on the OS heap.
nietod,

Hmmm, you disagreed with what I said and then said the same thing.

True malloc and new allocate from the CRT "heap" but where does the CRT get it's heap?  GlobalAlloc().

There is only one "true" source of memory on Win32, GlobalAlloc().  All other "sources" of memory are eventually going back to this source.

It's like saying I have 3 sources of water in my house, the kitchen sink, the bathtub, and the outside hose faucet.  So if one runs out, I can just use another.  Doesn't work, they are come out of the same source....
>> malloc and new allocate from the CRT "heap" but where
>> does the CRT get it's heap?  GlobalAlloc()
But the RTL (usually) allocates a heap inside of the OS's heap.  So the allocations performed by the C/C++ RTL do not alter the OS's heap, this keeps that heap streamlined and running efficiently.  That is not what you said, or at least that is not what

"They [new and malloc] are both "wrappers" around the GlobalAlloc function"

suggests to me.  It sounds to me like it says that new and malloc are actually using GlobalAlloc(), which is unlikely to be true.  Most likely GlobalAlloc() was used when the program was started to create the heap memory and then never used again.
I guess that depends on the definition of "wrapper" doesn't it.  

Depending on the design of the CRT, it could be very thin to "thick as a brick".  My intention was to describe it in general terms and I didn't mean to imply that each call to malloc ends up calling GlobalAlloc.  But I do mean to imply that if you were to trace back where malloc is getting it memory from it will be from a GlobalAlloc call somewhere in the life of the system.

Guys, this is an extract from the MSDN about both "GlobalAlloc" and "LocalAlloc":

[...]

This function is provided only for compatibility with 16-bit versions of Windows.

[...]

So please stop talking about GlobalAlloc.

For 32bit Windows we have two different allocation techniques: VirtualAlloc and HeapCreate/HeapAlloc, whereas VirtualAlloc is for bigger blocks and Heap* is for finer allocations. HeapAlloc even calls VirtualAlloc internally for bigger blocks.
Actually, the MSDN docs are a little "premature"  You must use GlobalAlloc for some things, like to create handles for data to be placed on the clipboard or for DEVNAMES structures used by the print setup dialog etc.  

>> 32bit Windows we have two different allocation
>> techniques: VirtualAlloc and HeapCreate/HeapAlloc,
And GlobalAlloc() and all have very different advantages and dissadvantages so they really can't be interchanged.  

For example GlobalAlloc() allocates blocks with a 4 k granularity.  So it is not good for small allocations.  It directly affects the OS's heap, so it is not good for numerous allocations.  GlobalAlloc allows mopvable blocks to be allocated that don't have as dramatic an impact on the heap's performance,  This is good for large and infrequently accessed blocks.  VirtualAlloc allocates with a 64K granularity.  So it REALLY isn't good for small allocations.  it allows you to reserve portions of virtual memory without actually consuming physical memory (virtual memory storage).  It also affects the OS's heap directly, so shouldn't be used for numerious allocations.  Also if you need to commit the memory immediately, it is more direct to use GlobalAlloc().  heapAlloc() allocates from a "sub-heap" with a 32 byte granularity.  So it is good for small allocatons.  It does not affect the OS heap so it good for frequent allcoations.  It uses a considerably smaller heap than GlobalAlloc() and VirtualAlloc()  so it it not as good for huge (say like a meg) allocations.
Okay, but if someone asks "which allocation method should I use?", we shouldn't tell him to use a method which is (according to Microsoft) only provided for backward compatibility - even if this statement is not completely true. Don't you think so? I think you've given the right answer already. VirtualAlloc allocated 64k blocks, so it is not good for frequent allocations (so my first comment is not a good one). The best suggestion seems to be your first suggestion, namely HeapCreate/HeapAlloc.

BTW, what did you mean with that:

"Allocate tte heap memory with GlobaAlloc().  Then use HeapCreate() to convert it to a heap"

? I mean, HeapCreate is working alone, without calling GlobalAlloc before. I didn't find anything about "convertion"...
It really depends on the circumstances.  While I would agree with you for most circumstances, I would not completely dismiss GlobalAlloc().  

I suspect that in this case, HeapCreate() is the way to go.

>> Allocate tte heap memory with GlobaAlloc().  
>> Then use HeapCreate() to convert it to a heap"
In win16 there was a function that you could call to convert an allready allocated block of memory to a heap.  (Often used to create a heap in a program's DGROUP data segment.)  I was thinking that HeapCreate() worked that way, i.e. that you specify the memory to be used as a heap.)
Avatar of nils pipenbrinck

ASKER

Adjusted points to 100
folks..

Thank you.. the informations about the granularity where very iteresting for me. I'll rewrite my code and use HeapAlloc from now on.. I guess that the 4k granularity of LocalAlloc is to much overhead for me.

I don't care about the system overhead that much since I'll only allocate memory during initialisation. Afterwardws I'll do a multimedia presentation which does nothing but do directdraw flipping and eat cpu time (no allocs)..

anyways.. 4k granularity is way to much overhead for me.. 32 bytes is perfect.

Hm.. I think 50 points are a little bit few for your work.. I'll raise it a little bit. thanks for all the interesting comments..

Nils
I think this was quite an interesting discussion and I would like to invite you (experts) to continue to one concerning a similiar (or almost the same) subject.

https://www.experts-exchange.com/questions/20536762/Local-Global-Heap-Alloc-which-to-use.html
Which dynamic memory allocation method to use?

--Filip