malloc()和HeapAlloc()之间有什么区别?据我所知,malloc从堆中分配内存,就像HeapAlloc一样,对吗?那么有什么区别呢?
wkyowqbh1#
事实上malloc()(和其他C运行时堆函数)是模块相关的,这意味着如果调用malloc一个模块的代码中的()(即DLL),则应调用free(),否则您可能会遭受一些相当严重的堆损坏(这一点已被详细记录)。使用HeapAlloc()与获取进程堆()而不是malloc(),包括重载new和delete运算符以使用此类、允许您在模块之间传递动态分配的对象,如果在一个模块的代码中分配内存,而在指向内存块已传递到外部模块。
z9smfwbn2#
你说得对,它们都是从堆中分配内存的,但是它们之间有区别:
malloc()
HeapAlloc()
在Windows上,malloc很有可能在HeapAlloc之上实现,我希望malloc比HeapAlloc更快。HeapAlloc比malloc有更大的灵活性。特别是,它允许您指定要从哪个堆进行分配。这可以满足每个进程多个堆的需要。对于几乎所有的编码场景,您都应该使用malloc而不是HeapAlloc。虽然您将问题标记为C++,但我希望您使用new!
malloc
HeapAlloc
new
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()的内存开销而言,开销非常低。
_heap_alloc_base()
malloc.c
return HeapAlloc(_crtheap, 0, size)
_crtheap
HeapCreate()
bis0qfac4#
malloc是C标准库(也是C++标准库)中的函数。HeapAlloc是一个Windows API函数。后者允许您指定从哪个堆进行分配,我认为这对于避免不同线程中分配请求的序列化非常有用(注意HEAP_NO_SERIALIZE标志)。
HEAP_NO_SERIALIZE
kgsdhlau5#
在多个DLL可以进出(通过LoadLibrary/Freelibrary)的系统中,当内存可以在一个DLL中分配,但在另一个DLL中释放时(参见前面的答案),HeapAlloc和相关函数似乎是成功共享内存的最小公分母。HeapAlloc是线程安全的,可能是由大量博士高度优化的,它似乎可以在我们使用malloc/free的不太可共享的代码失败的各种情况下工作。我们是一个C++嵌入式商店,所以我们在系统中重载了new/delete操作符,以使用HeapAlloc(GetProcessHeap()),它可以存根(在目标上)或本地(在Windows上)以实现代码可移植性。到目前为止没有问题,现在我们已经绕过了malloc/free,这似乎是无可争议的DLL具体,一个新的“堆”为每个DLL加载。
ivqmmu1c6#
此外,您还可以参考:https://msdn.microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx这表明您可以启用WinApi内存分配器管理的堆的一些功能,例如“HeapEnableTerminationOnCorruption”。据我所知,它提供了一些基本的堆溢出保护,这些保护在安全性方面可以被认为是应用程序的附加值。(eg,我宁愿崩溃我的应用程序(作为应用程序所有者),而不是执行任意代码)另一件事是,它可能在开发的早期阶段很有用,所以你可以在进入生产之前发现内存问题。
cotxawn77#
C运行时库dll名称从visual studio版本更改为版本。
yv5phkfx8#
以下是微软对此的看法:http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx到目前为止,有一件事是这样的:“malloc函数的缺点是依赖于运行时。new运算符的缺点是依赖于编译器和语言。”此外,“如果无法分配内存,可以指示HeapAlloc引发异常”因此,如果你想让你的程序在任何CRT下运行,或者根本不使用CRT,你可以使用HeapAlloc。也许只有恶意软件编写者才会这么做。另一个用途可能是,如果你正在编写一个内存非常密集的应用程序,使用特定的内存分配/使用模式,你宁愿编写自己的堆分配器,而不是使用CRT。
8条答案
按热度按时间wkyowqbh1#
事实上malloc()(和其他C运行时堆函数)是模块相关的,这意味着如果调用malloc一个模块的代码中的()(即DLL),则应调用free(),否则您可能会遭受一些相当严重的堆损坏(这一点已被详细记录)。使用HeapAlloc()与获取进程堆()而不是malloc(),包括重载new和delete运算符以使用此类、允许您在模块之间传递动态分配的对象,如果在一个模块的代码中分配内存,而在指向内存块已传递到外部模块。
z9smfwbn2#
你说得对,它们都是从堆中分配内存的,但是它们之间有区别:
malloc()
是可移植的,是标准的一部分。HeapAlloc()
是不可移植的,它是Windows API函数。在Windows上,
malloc
很有可能在HeapAlloc
之上实现,我希望malloc
比HeapAlloc
更快。HeapAlloc
比malloc
有更大的灵活性。特别是,它允许您指定要从哪个堆进行分配。这可以满足每个进程多个堆的需要。对于几乎所有的编码场景,您都应该使用
malloc
而不是HeapAlloc
。虽然您将问题标记为C++,但我希望您使用new
!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()
的内存开销而言,开销非常低。bis0qfac4#
malloc
是C标准库(也是C++标准库)中的函数。HeapAlloc
是一个Windows API函数。后者允许您指定从哪个堆进行分配,我认为这对于避免不同线程中分配请求的序列化非常有用(注意
HEAP_NO_SERIALIZE
标志)。kgsdhlau5#
在多个DLL可以进出(通过LoadLibrary/Freelibrary)的系统中,当内存可以在一个DLL中分配,但在另一个DLL中释放时(参见前面的答案),HeapAlloc和相关函数似乎是成功共享内存的最小公分母。
HeapAlloc是线程安全的,可能是由大量博士高度优化的,它似乎可以在我们使用malloc/free的不太可共享的代码失败的各种情况下工作。
我们是一个C++嵌入式商店,所以我们在系统中重载了new/delete操作符,以使用HeapAlloc(GetProcessHeap()),它可以存根(在目标上)或本地(在Windows上)以实现代码可移植性。
到目前为止没有问题,现在我们已经绕过了malloc/free,这似乎是无可争议的DLL具体,一个新的“堆”为每个DLL加载。
ivqmmu1c6#
此外,您还可以参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx
这表明您可以启用WinApi内存分配器管理的堆的一些功能,例如“HeapEnableTerminationOnCorruption”。
据我所知,它提供了一些基本的堆溢出保护,这些保护在安全性方面可以被认为是应用程序的附加值。
(eg,我宁愿崩溃我的应用程序(作为应用程序所有者),而不是执行任意代码)
另一件事是,它可能在开发的早期阶段很有用,所以你可以在进入生产之前发现内存问题。
cotxawn77#
C运行时库dll名称从visual studio版本更改为版本。
yv5phkfx8#
以下是微软对此的看法:http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx
到目前为止,有一件事是这样的:“malloc函数的缺点是依赖于运行时。new运算符的缺点是依赖于编译器和语言。”
此外,“如果无法分配内存,可以指示HeapAlloc引发异常”
因此,如果你想让你的程序在任何CRT下运行,或者根本不使用CRT,你可以使用HeapAlloc。也许只有恶意软件编写者才会这么做。另一个用途可能是,如果你正在编写一个内存非常密集的应用程序,使用特定的内存分配/使用模式,你宁愿编写自己的堆分配器,而不是使用CRT。