malloc 和 HeapAlloc 之间有根本区别吗(除了可移植性之外)?

发布于 2024-10-09 20:48:07 字数 738 浏览 6 评论 0原文

由于各种原因,我正在尝试将代码从 C 运行时移植到使用 Windows 堆 API 的代码。我遇到了一个问题:如果我将 malloc/calloc/realloc/free 调用重定向到 HeapAlloc/HeapReAlloc/HeapFree(使用GetProcessHeap作为句柄),内存似乎分配正确(没有坏指针返回,并且没有抛出异常),但是我正在移植的库由于某种原因说“无法分配内存”。

我已经用 Microsoft CRT(它使用下面的堆 API)和另一家公司的运行时库(它使用下面的全局内存 API)进行了尝试;这两者的 malloc 都可以很好地与库配合使用,但由于某种原因,直接使用堆 API 不起作用。

我检查过分配量并不太大(>= 0x7FFF8 字节),事实并非如此。

我能想到的唯一问题是内存对齐;是这样吗?或者除此之外,堆 API 和 CRT 内存 API 之间是否存在我不知道的根本区别?

如果是这样,那是什么?如果不是,那么为什么静态 Microsoft CRT(包含在 Visual Studio 中)在调用 之前在 malloc/calloc 中采取一些额外的步骤>堆分配?我怀疑有什么不同,但我想不出它可能是什么。

谢谢你!

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 correctly (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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰つ倒转 2024-10-16 20:48:07

正如我通过艰难的方式发现的那样...

区别并不是根本性的,但是 HeapReAlloc (使用 RtlReAllocateHeap)确实不会自动处理空指针作为调用HeapAlloc的提示;它反而失败了。

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.

流绪微梦 2024-10-16 20:48:07

另一个重要的区别:

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

具有未定义的行为< /a>,而

void *ptr = NULL;
free(ptr);

定义良好(未执行任何操作)。

更新 2021:

HeapFree 文档 已于 2021 年 1 月更新,现在声明:

[输入] lpMem

指向要释放的内存块的指针。该指针由以下函数返回
HeapAlloc 或 HeapReAlloc 函数。该指针可以为NULL

老实说,目前尚不清楚这是否适用于特定 SDK 版本或以后。可以肯定的是,该参数已在 10.0.16299.0 上标有 _Frees_ptr_opt_ ,因此可能只是一个文档问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文