c++ 内存分配()与堆分配()

mitkmikd  于 2022-11-27  发布在  其他
关注(0)|答案(8)|浏览(327)

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

wkyowqbh

wkyowqbh1#

事实上malloc()(和其他C运行时堆函数)是模块相关的,这意味着如果调用malloc一个模块的代码中的()(即DLL),则应调用free(),否则您可能会遭受一些相当严重的堆损坏(这一点已被详细记录)。使用HeapAlloc()与获取进程堆()而不是malloc(),包括重载new和delete运算符以使用此类、允许您在模块之间传递动态分配的对象,如果在一个模块的代码中分配内存,而在指向内存块已传递到外部模块。

z9smfwbn

z9smfwbn2#

你说得对,它们都是从堆中分配内存的,但是它们之间有区别:

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

在Windows上,malloc很有可能在HeapAlloc之上实现,我希望mallocHeapAlloc更快。
HeapAllocmalloc有更大的灵活性。特别是,它允许您指定要从哪个堆进行分配。这可以满足每个进程多个堆的需要。
对于几乎所有的编码场景,您都应该使用malloc而不是HeapAlloc。虽然您将问题标记为C++,但我希望您使用new

vptzau2j

vptzau2j3#

在Visual C++中,函式malloc()或运算子new最后会呼叫HeapAlloc()。如果您两柴程式码,就会发现函式_heap_alloc_base()(在档案malloc.c中)正在呼叫return HeapAlloc(_crtheap, 0, size),其中_crtheap是以HeapCreate()建立的全域堆积。
函数HeapAlloc()在最小化内存开销方面做得很好,每次分配最少有8个字节的开销。我所见过的最大的内存开销是每次分配15个字节,分配范围从1个字节到100,000个字节。较大的块有较大的开销,但作为总分配的百分比,它仍然不到有效负载的2.5%。
我不能对性能发表评论,因为我还没有用定制的例程对HeapAlloc()进行基准测试,但是就使用HeapAlloc()的内存开销而言,开销非常低。

bis0qfac

bis0qfac4#

malloc是C标准库(也是C++标准库)中的函数。
HeapAlloc是一个Windows API函数。
后者允许您指定从哪个堆进行分配,我认为这对于避免不同线程中分配请求的序列化非常有用(注意HEAP_NO_SERIALIZE标志)。

kgsdhlau

kgsdhlau5#

在多个DLL可以进出(通过LoadLibrary/Freelibrary)的系统中,当内存可以在一个DLL中分配,但在另一个DLL中释放时(参见前面的答案),HeapAlloc和相关函数似乎是成功共享内存的最小公分母。
HeapAlloc是线程安全的,可能是由大量博士高度优化的,它似乎可以在我们使用malloc/free的不太可共享的代码失败的各种情况下工作。
我们是一个C++嵌入式商店,所以我们在系统中重载了new/delete操作符,以使用HeapAlloc(GetProcessHeap()),它可以存根(在目标上)或本地(在Windows上)以实现代码可移植性。
到目前为止没有问题,现在我们已经绕过了malloc/free,这似乎是无可争议的DLL具体,一个新的“堆”为每个DLL加载。

ivqmmu1c

ivqmmu1c6#

此外,您还可以参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx
这表明您可以启用WinApi内存分配器管理的堆的一些功能,例如“HeapEnableTerminationOnCorruption”。
据我所知,它提供了一些基本的堆溢出保护,这些保护在安全性方面可以被认为是应用程序的附加值。
(eg,我宁愿崩溃我的应用程序(作为应用程序所有者),而不是执行任意代码)
另一件事是,它可能在开发的早期阶段很有用,所以你可以在进入生产之前发现内存问题。

cotxawn7

cotxawn77#

  • malloc* 是C运行时库(CRT)导出的函数,该函数是编译器特定的。

C运行时库dll名称从visual studio版本更改为版本。

  • HeapAlloc* 函数由windows文件夹中的kernel32.dll导出。
yv5phkfx

yv5phkfx8#

以下是微软对此的看法:http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx
到目前为止,有一件事是这样的:“malloc函数的缺点是依赖于运行时。new运算符的缺点是依赖于编译器和语言。”
此外,“如果无法分配内存,可以指示HeapAlloc引发异常”
因此,如果你想让你的程序在任何CRT下运行,或者根本不使用CRT,你可以使用HeapAlloc。也许只有恶意软件编写者才会这么做。另一个用途可能是,如果你正在编写一个内存非常密集的应用程序,使用特定的内存分配/使用模式,你宁愿编写自己的堆分配器,而不是使用CRT。

相关问题