开发者

Is there a fundamental difference between malloc and HeapAlloc (aside from the portability)? [duplicate]

This question already has answers here: malloc() vs. HeapAlloc() (8 answers) Closed 2 years ago.

I'm having code that, for various reasons, I'm trying to port from the C runtime to one that uses the Windows Heap API. I've encountered a problem: If I redirect the malloc/calloc/realloc/free calls to HeapAlloc/HeapReAlloc/HeapFree (with GetProcessHeap for the handle), the memory seems to be allocated correc开发者_运维知识库tly (no bad pointer returned, and no exceptions thrown), but the library I'm porting says "failed to allocate memory" for some reason.

I've tried this both with the Microsoft CRT (which uses the Heap API underneath) and with another company's run-time library (which uses the Global Memory API underneath); the malloc for both of those works well with the library, but for some reason, using the Heap API directly doesn't work.

I've checked that the allocations aren't too big (>= 0x7FFF8 bytes), and they're not.

The only problem I can think of is memory alignment; is that the case? Or other than that, is there a fundamental difference between the Heap API and the CRT memory API that I'm not aware of?

If so, what is it? And if not, then why does the static Microsoft CRT (included with Visual Studio) take some extra steps in malloc/calloc before calling HeapAlloc? I'm suspecting there's a difference but I can't think of what it might be.

Thank you!


As I found out the hard way...

The difference isn't fundamental, but HeapReAlloc (which uses RtlReAllocateHeap) does not automatically treat a null pointer as a hint to call HeapAlloc; it fails instead.


Another important difference:

void *ptr = NULL;
HeapFree(GetProcessHeap(), 0, ptr);

has undefined behavior, while

void *ptr = NULL;
free(ptr);

is well defined (no operation performed).

UPDATE 2021:

The HeapFree documentation has been updated in January 2021, and now states:

[in] lpMem

A pointer to the memory block to be freed. This pointer is returned by the HeapAlloc or HeapReAlloc function. This pointer can be NULL.

Honestly, it is not clear whether this applies since a specific SDK release or since ever. For sure that parameter was marked with _Frees_ptr_opt_ already on 10.0.16299.0, so probably was just a documentation issue.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜