What is the difference of

LocalAlloc(length);
and
HeapAlloc(GetProcessHeap(),0,length);

?

I couldn't find the difference within performance. :(

Please give me a help.
Thank you for reading.
Have a happy day. :)
Posted on 2005-08-08 08:53:37 by nyam
nyam,

Recent benchmarking shows HeapAlloc() to be faster on small allocations. LocalAlloc() is functionally the same as GlobalAlloc() as the LOCAL/GLOBAL distinction that derived from 16 bit windows in no longer valid. GlobalAlloc() is really only useful with fixed memory, the other styles reflect 16 bit windows considerations.
Posted on 2005-08-08 09:03:11 by hutch--
On NT systems, Local/GlobalAlloc end up calling the heap allocation routines, just with a "magic flag" set. Thus it does use a few more instructions, but not enough that you can really time it. HeapAlloc will be a little faster though, even if you can't measure it :p

It also gives you a bit more control - like HEAP_NO_SERIALIZE and HEAP_GENERATE_EXCEPTIONS.

Also note that there are occasions where you *have* to use GlobalAlloc, like when dealing with the clipboard or CreateStreamOnHGlobal .
Posted on 2005-08-08 09:07:06 by f0dder

Recent benchmarking shows HeapAlloc() to be faster on small allocations. LocalAlloc() is functionally the same as GlobalAlloc() as the LOCAL/GLOBAL distinction that derived from 16 bit windows in no longer valid. GlobalAlloc() is really only useful with fixed memory, the other styles reflect 16 bit windows considerations.


Thank you hutch-- for your great reply.
It really helps me. :)

If so, Is it better to use LocalAlloc(GlobalAlloc) than HeapAlloc with large allocations ?
Thank you very much. :)
Posted on 2005-08-08 09:12:03 by nyam

On NT systems, Local/GlobalAlloc end up calling the heap allocation routines, just with a "magic flag" set. Thus it does use a few more instructions, but not enough that you can really time it. HeapAlloc will be a little faster though, even if you can't measure it :p

It also gives you a bit more control - like HEAP_NO_SERIALIZE and HEAP_GENERATE_EXCEPTIONS.

Also note that there are occasions where you *have* to use GlobalAlloc, like when dealing with the clipboard or CreateStreamOnHGlobal .



Thank you f0dder. :)
It really helps me. :)
For the speed, I'll use HeapAlloc (It'll use HeapAlloc even if I can't measure it as you said.)
Thank you. :)
Posted on 2005-08-08 09:14:20 by nyam
Also, remember that if you use Local/GlobalAlloc, you must only use the memory if you supply the GMEM_FIXED parameter - otherwise it's a handle.

You can call GetProcessHeap at the start of your program and save the handle somewhere, as the process heap doesn't change during program execution. Not that the code executed by GetProcessHeap is a lot.

If you want to do really large allocations, look into VirtualAlloc - it provides even more flexibility.
Posted on 2005-08-08 09:18:21 by f0dder

Also, remember that if you use Local/GlobalAlloc, you must only use the memory if you supply the GMEM_FIXED parameter - otherwise it's a handle.

You can call GetProcessHeap at the start of your program and save the handle somewhere, as the process heap doesn't change during program execution. Not that the code executed by GetProcessHeap is a lot.

If you want to do really large allocations, look into VirtualAlloc - it provides even more flexibility.



Thank you f0dder. :)
Fortunately, I have used LocalAlloc(GlobalAlloc) always with GMEM_FIXED. :)
I'll consider to save the handle to global value as you said. :)
Thank you!
Posted on 2005-08-08 10:23:47 by nyam
when working on nt/xp boxes a little speed up for VirtualAlloc is

    push 4 ;readwrite
    push 1000h ;mem commit
    push memSize ; address of dword holding size of memory to allocate
    push 0          ; i forget what this is for check some undocumented api site
    push memAddr ; address of dword which the address of the memory will be returned to
    push -1          ;magic flag :]
    call
    mov eax, dword

Since calling VirtualAlloc calls VirtualAllocEx which then calls NtAllocateVirtualMemory, you save like 40bytes of execution by using the Nt* function.
Posted on 2005-08-08 20:07:06 by r22
Why do you call NtAllocateVirtualMemory indirectly? And what's with the magic numbers instead of symbolic constants?
Posted on 2005-08-08 20:24:59 by f0dder
I do what works for me, and that works for me.  :lol:
Posted on 2005-08-08 22:07:49 by r22
NtAllocateVirtualMemory
(
NtCurrentProcess(),
(PVOID)&Buf,
0,
&SectionSize,
MEM_COMMIT,
PAGE_READWRITE
);

NTOSAPI NTSTATUS NTAPI NtAllocateVirtualMemory  (  IN HANDLE  ProcessHandle, 
  IN OUT PVOID *  BaseAddress, 
  IN ULONG  ZeroBits, 
  IN OUT PULONG  AllocationSize, 
  IN ULONG  AllocationType, 
  IN ULONG  Protect


and GetCurrentProcess almost always return -1
so it is just hardcoded as some magic value
Posted on 2005-08-09 05:59:46 by bluffer
...and the code is less easy to read than a normal "invoke VirtualAlloc, whatever", only works on NT, and might break on future versions - all this, without really gaining anything :)
Posted on 2005-08-09 06:02:41 by f0dder
also i think there is no ntdll.inc or ntdll.lib so one would probably have to do LoadLib (ntdll) Getproc(NtAlloc)
do push push and call eax :) so the 40 bytes saved is spent elsewhere :)
ok ntdll is mapped on all process still one has to GetModuleHandle() or use some other hardcoded
push 7ff80000 :(
unless writing shell code its of no use in direct programming
if using shell code
then one could directly
push push and call int 2e or sysenter :) it saves even more bytes :)
Posted on 2005-08-09 06:07:42 by bluffer

also i think there is not ntdll.inc or ntdll.lib so one would probably have to do LoadLib (ntdll) Getproc(NtAlloc)

Nah, just make your own includes - hardly a problem.


unless writing shell code its of no use in direct programming if using shell code then one could directly push push and call int 2e or sysenter Smile i saves even more bytes

If one is writing shellcode, one should have a spanking.
Posted on 2005-08-09 06:14:31 by f0dder
hehe f0dder ,should be spanked huh
there are lot of legitimate reasons to write shell code how do you think those who find
vulnerabilities in your favourite software do it :) weaving a magic wand and voila a pari comes up in dream and informs you of the vulnerability :)
nope :)
any way
lets drop the subject else this gets converted and diverted into some thing the poster didnt intend to read :)
Posted on 2005-08-09 06:47:46 by bluffer
Well, I was thinking of the people that write shellcode with malicious intent - and those that release proof of concept before developers have had time to fix their software. Apart from that, I agree that research has to be done - if we don't find the bugs, the malicious people do.
Posted on 2005-08-09 06:53:13 by f0dder
nyam,

The general drift with memory allocation is to pick a strategy that best suits the task you have in mind. Something simple like allocation 1 meg of memory can be done by anything with no appreciable difference but if you are faced with a code design that MUST allocate memory in small pieces every iteration, the strategy you use becomes a factor. Windows has a wide range of techniques available to handle different tasks and being familiar with them makes you selection a lot easier.

If the task you are undertaking involves many thousands to millions of allocations, you get far better performance if you allocate larger blocks and manage the distribution and reallocation yourself as high count looping of memory allocaion is slow in comparison. A character tree is a good example here where you may handle millions of seperate requests and cutting down that many allocations is a direct performance factor.
Posted on 2005-08-09 19:40:06 by hutch--
As Ultrano and I found out the hard way, which led to him developing a paged memory manager library which he called "smalloc" ("small allocator") - it operated by allocating one or more blocks of memory for each "struct size" that you exposed it to.. for example, all allocations of 32 bytes would exist on the same page(s), and it used a bitpattern to identify occupied / freed "holes in the array"...

The reason why we went this way is that previously we had both been relying on the Heap manager to allocate small blocks, which is a really bad idea - it leads to "heap fragmentation" .. and it gets worse... the Heap has a "defragment" function which is simply not very good, and it has a "ReAlloc" function which is similarly bad - we found that small allocation requests would begin failing under load, yet at the same time, larger allocations would succeed !! The solution became quite obvious..
Posted on 2005-08-09 23:59:35 by Homer
Lots of small allocations are fine - repeated allocations/deallocations with varying sizes is going to kill you (fragmentation). Not to mention that you can do faster than the heap manager for fixed-size allocs. <3 object pools <3.

For generic allocations, there's the Low-Fragmentation Heap stuff, but it's XP-only iirc... there's various ways to impement your own low-fragmentation heap though, either on top of HeapAlloc or (more appropriately) VirtualAlloc.
Posted on 2005-08-10 06:50:46 by f0dder

if using shell code
then one could directly
push push and call int 2e or sysenter :) it saves even more bytes :)


You'd have to first read the actual system call number from the ntdll stub that you wanted to use prior to doing this (rather than using a hardcoded system call number).  Otherwise, your code would not be portable across various versions of Windows NT.  See http://www.metasploit.com/users/opcode/syscalls.html for more details.
Posted on 2005-08-13 11:26:51 by nohaven