72

What is the difference between malloc() and HeapAlloc()? As far as I understand malloc allocates memory from the heap, just as HeapAlloc, right?

So what is the difference?

0

8 Answers 8

107

Actually, malloc() (and other C runtime heap functions) are module dependant, which means that if you call malloc() in code from one module (i.e. a DLL), then you should call free() within code of the same module or you could suffer some pretty bad heap corruption (and this has been well documented). Using HeapAlloc() with GetProcessHeap() instead of malloc(), including overloading new and delete operators to make use of such, allow you to pass dynamically allocated objects between modules and not have to worry about memory corruption if memory is allocated in code of one module and freed in code of another module once the pointer to a block of memory has been passed across to an external module.

Sign up to request clarification or add additional context in comments.

5 Comments

Finally, this is the most important answer here. malloc() is portable but when you need to move objects and DLLs get involved, you need the Heap. For Windows developers, I suggest using the Heap and writing a custom STL allocator for the Heap too.
Is the objection still valid? For example VC 2013 CRT initializes the _crtheap as GetProcessHeap(), so malloc/free from different DLLs should already use the same GetProcessHeap(). There is a different story if mixing 'release' and 'debug' CRTs. The later adds an offset to the returned pointer, so indeed allocating by the debug-versions and freeing by the release-version (or reverse) will crash the program.
Would love a link to the "well documented" that you mention.
"if you call malloc() in code from one module (i.e. a DLL), then you should call free() within code of the same module" This requirement can't possibly be compliant with the C standard, can it?
@OskarSkog C standard doesn't specify anything about modules in Windows sense.
64

You are right that they both allocate memory from a heap. But there are differences:

  • malloc() is portable, part of the standard.
  • HeapAlloc() is not portable, it's a Windows API function.

It's quite possible that, on Windows, malloc would be implemented on top of HeapAlloc. I would expect malloc to be faster than HeapAlloc.

HeapAlloc has more flexibility than malloc. In particular it allows you to specify which heap you wish to allocate from. This caters for multiple heaps per process.

For almost all coding scenarios you would use malloc rather than HeapAlloc. Although since you tagged your question C++, I would expect you to be using new!

10 Comments

How could malloc be faster than HeapAlloc if it's implemented on top of HeapAlloc?
@dan04 Because malloc may implement further sub allocation patterns.
@drhirsch: "trap for inexperienced developers" sure; "serves no other purpose," not so much. You can use it with per thread heaps or allocate memory from a heap which is executable.
it has some other purpose, like being used in languages other than C or C++. There are actually more programmers than those who use C or C++.
@drhirsh: what MS is doing here is no different than what happens on other platforms; malloc() is rarely (ever?) supplied directly by the OS, but instead the C library implements it in terms of an underlying OS primitive. On Win32, it's HeapAlloc(); on unix, malloc() is typically implemented in terms of either sbrk() or mmap(). A similar situation exists with files: C's fopen() is implemented in terms of CreateFile() on Win32, or open() on unix. The OP's qu here is really analogous to "fopen() vs open()" or "fopen() vs CreateFile()".
|
35

With Visual C++, the function malloc() or the operator new eventually calls HeapAlloc(). If you debug the code, you will find the function _heap_alloc_base() (in the file malloc.c) is calling return HeapAlloc(_crtheap, 0, size) where _crtheap is a global heap created with HeapCreate().

The function HeapAlloc() does a good job to minimize the memory overhead, with a minimum of 8 bytes overhead per allocation. The largest I have seen is 15 bytes per allocation, for allocations ranging from 1 byte to 100,000 bytes. Larger blocks have larger overhead, however as a percent of the total allocated it remains less than 2.5% of the payload.

I cannot comment on performance because I have not benchmarked the HeapAlloc() with a custom made routine, however as far as the memory overhead of using HeapAlloc() is concerned, the overhead is amazingly low.

2 Comments

and HeapAlloc() calls RtlHeapAlloc() implemented in ntdll.dll, kernel32.dll, kernalebase.dll
I have a benchmark in my open address hash map sourceforge.net/projects/cgenericopenaddresshashmap that suggests that Windows 8 malloc is at least 5 times faster than Windows 7. Somebody suggested here that MS CRT malloc does nothing more than wrap HeapAlloc, do you confirm ?
7

malloc is a function in the C standard library (and also in the C++ standard library).

HeapAlloc is a Windows API function.

The latter lets you specify the heap to allocate from, which I imagine can be useful for avoiding serialization of allocation requests in different threads (note the HEAP_NO_SERIALIZE flag).

Comments

3

In systems where multiple DLLs may come and go (via LoadLibrary/Freelibrary), and when memory may be allocated within one DLL, but freed in another (see previous answer), HeapAlloc and related functions seem to be the least-common-denominator for successful memory sharing.

Thread safe, presumably highly optimized by PhDs galore, HeapAlloc appears to work in all kinds of situations where our not-so-shareable code using malloc/free would fail.

We are a C++ embedded shop, so we have overloaded operator new/delete across our system to use the HeapAlloc( GetProcessHeap( ) ) which can stubbed (on target) or native (to windows) for code portability.

So far no problems now that we have bypassed malloc/free which seem indisputably DLL specifically, a new "heap" for each DLL load.

Comments

2

Additionally, you can refer to:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx

Which stands that you can enable some features of the HEAP managed by WinApi memory allocator, eg "HeapEnableTerminationOnCorruption".

As I understand, it makes some basic heap overflow protections which may be considered as an added value to your application in terms of security.

(eg, I would prefer to crash my app (as an app owner) rather than execute arbitrary code)

Other thing is that it might be useful in early phase of development, so you could catch memory issues before going to the production.

Comments

-1

malloc is exported function by C run-time library(CRT) which is compiler specific.
C run-time library dll name changes from visual studio versions to versions.

HeapAlloc function is exported by kernel32.dll present in windows folder.

Comments

-2

This is what MS has to say about it: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx

One thing one one mentioned thus far is: "The malloc function has the disadvantage of being run-time dependent. The new operator has the disadvantage of being compiler dependent and language dependent."

Also, "HeapAlloc can be instructed to raise an exception if memory could not be allocated"

So if you want your program to run with any CRT, or perhaps no CRT at all, you'd use HeapAlloc. Perhaps only people who would do such thing would be malware writers. Another use might be if you are writing a very memory intensive application with specific memory allocation/usage patterns that you'd rather write your own heap allocator instead of using a CRT one.

1 Comment

i know I'm a decade late, but there's a lot of good reasons you might want to use HeapAlloc directly. The most obvious is that every global allocator has a lock - having a separate memory source from the main memory source allows you to minimize contention. You can even disable the internal lock and provide customized synchronization around HeapAlloc based on your code's particular needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.