malloc()与HeapAlloc()

时间:2011-11-22 09:14:24

标签: c++ winapi malloc

malloc()和HeapAlloc()有什么区别?据我所知,malloc从堆中分配内存,就像HeapAlloc一样,对吗?

那有什么区别?

谢谢!

8 个答案:

答案 0 :(得分:72)

实际上,malloc()(和其他C运行时堆函数)是模块相关的,这意味着如果你从一个模块(即一个DLL)调用代码中的malloc(),那么你应该在代码中调用free()相同的模块或你可能遭受一些非常糟糕的堆损坏(这已被很好地记录)。使用HeapAlloc()和GetProcessHeap()而不是malloc(),包括重载new和delete运算符来使用它们,允许你在模块之间传递动态分配的对象,如果在代码中分配内存,则不必担心内存损坏一个模块,一旦指向内存块的指针传递到外部模块,就会释放另一个模块的代码。

答案 1 :(得分:45)

你是对的,他们都从堆中分配内存。但存在差异:

  • malloc()是便携式的,是标准的一部分。
  • HeapAlloc()不可移植,它是Windows API函数。

在Windows上,malloc很可能会在HeapAlloc之上实施。我希望mallocHeapAlloc快。

HeapAllocmalloc具有更大的灵活性。特别是它允许您指定要从中分配的堆。这适用于每个进程多个堆。

对于几乎所有编码方案,您都会使用malloc而不是HeapAlloc。虽然自从您标记了问题C ++,但我希望您使用new

答案 2 :(得分:23)

使用Visual C ++,函数malloc()或运算符new最终调用HeapAlloc()。如果您调试代码,您会发现函数_heap_alloc_base()(在文件malloc.c中)正在调用return HeapAlloc(_crtheap, 0, size),其中_crtheap是使用{{1}创建的全局堆}。

函数HeapCreate()可以很好地减少内存开销,每个分配最少8个字节的开销。我看到的最大值是每个分配15个字节,分配范围从1个字节到100,000个字节。较大的块具有较大的开销,但是作为分配总量的百分比,它仍然小于有效载荷的2.5%。

我无法评论性能,因为我没有使用自定义例程对HeapAlloc()进行基准测试,但是就使用HeapAlloc()的内存开销而言,开销非常低。

答案 3 :(得分:6)

malloc是C标准库(以及C ++标准库)中的一个函数。

HeapAlloc是Windows API函数。

后者允许您指定要分配的堆,我认为这可以用于避免在不同线程中对分配请求进行序列化(请注意HEAP_NO_SERIALIZE标志)。

干杯&第h。,

答案 4 :(得分:1)

此外,您可以参考:

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

您可以启用由WinApi内存分配器管理的HEAP的某些功能,例如“HeapEnableTerminationOnCorruption”。

据我了解,它提供了一些基本的堆溢出保护,可以在安全性方面将其视为应用程序的附加值。

(例如,我更愿意崩溃我的应用程序(作为应用程序所有者)而不是执行任意代码)

另一方面,它可能在开发的早期阶段很有用,因此您可以在进入生产之前捕获内存问题。

答案 5 :(得分:1)

在可能会来回移动多个DLL(通过LoadLibrary / Freelibrary)并且可能在一个DLL中分配内存但又在另一个DLL中释放内存的系统中(参见上一个答案),HeapAlloc和相关功能似乎是最不常见的-分母可以成功共享内存。

线程安全,大概是由博士们进行了高度优化,HeapAlloc似乎可以在所有无法使用malloc / free共享的代码失败的情况下工作。

我们是C ++嵌入式商店,因此我们在系统中已重载了运算符new / delete以使用HeapAlloc(GetProcessHeap()),该函数可以存根(在目标上)或本机(到Windows)以实现代码可移植性。

到目前为止,没有问题了,我们已经绕过了malloc / free,它似乎毫无疑问是DLL,每个DLL加载都有一个新的“堆”。

答案 6 :(得分:0)

这就是MS必须说的:http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx

到目前为止,提到的一件事是:“malloc函数的缺点是依赖于运行时。新的运算符具有依赖于编译器和语言的缺点。”

此外,“如果无法分配内存,可以指示HeapAlloc引发异常”

因此,如果您希望程序与任何CRT一起运行,或者根本不运行CRT,那么您将使用HeapAlloc。也许只有做这种事情的人才会是恶意软件编写者。另一个用途可能是如果你正在编写一个内存密集型应用程序,它具有特定的内存分配/使用模式,你宁愿编写自己的堆分配器,而不是使用CRT编写器。

答案 7 :(得分:0)

malloc 是C运行时库(CRT)导出的函数,C运行时库是特定于编译器的。
C运行时库dll名称从Visual Studio版本更改为版本。

HeapAlloc 函数由Windows文件夹中的kernel32.dll导出。