我引用MSDN http://msdn.microsoft.com/en-us/library/aa366533(VS.85).aspx:
malloc函数有 运行时的缺点 依赖。新的运营商有 编译器的缺点 依赖和语言依赖。
现在有问题的人:
a)我们的意思是malloc与运行时有关吗?什么样的动态内存分配函数可以独立于运行时?这句话听起来很奇怪。
b)新的语言依赖?当然应该是对的? HeapAlloc,LocalAlloc等语言是否独立?
c)从纯粹的性能角度来看,MSVC提供的例程更可取吗?
Arpan
答案 0 :(得分:4)
使用DLL时会出现malloc和new的问题。根据构建选项,DLL可能有自己的CRT副本。这使得它使用自己的堆来分配来自不同堆的内存,而不是EXE使用的堆。当一个模块分配内存并由另一个模块释放内存时,这会导致失败。使用STL时很常见。
解决这个问题的一种方法是使用/ MD选项编译代码。这会强制使用存储在自己的DLL中的CRT的共享副本。问题解决了,现在只有一个分配器,使用一个堆。
这个问题也出现在COM中,它允许不同的语言互操作。它们当然永远不会共享分配器,因为这些语言具有不同的运行时支持库。通过契约,COM代码必须使用COM运行时支持CoTaskMemAlloc()提供的单个分配器。
请注意,HeapAlloc()无法解决此问题。它需要一个堆的句柄,由HeapCreate()返回。不同的模块必须共享该句柄以避免麻烦。
更新:在VS2012中解决,CRT现在从共享堆分配,默认进程堆(GetProcessHeap函数)。
答案 1 :(得分:1)
a)在这种情况下,我认为他们将“运行时库”改为“运行时”。换句话说,它取决于C库中的实现。
b)确实新的是C ++特定的。 HeapAlloc等在技术上可用于C和C ++。
c)它们不能用于创建C ++对象,因为它们不会调用构造函数,因此这一点非常没有意义。在C ++中,您应该使用new和delete。
答案 2 :(得分:0)
a)这意味着malloc的行为取决于您编译的C运行库的版本。
b)HeapAlloc和LocalAlloc是Win32 API函数。它们确实是运行时和语言无关的。
c)如果不知道如何实现运行时例程,就无法回答。我怀疑他们的表现是可以比拟的。在任何情况下,如果你使用new运算符,那么你总是可以选择在以后必要时覆盖它。请记住,过早优化是万恶之源。 ;)
最后一点:LocalAlloc和GlobalAlloc 慢。除非被一个狡猾的旧Win32 API强行使用,否则不应该使用它们。
答案 3 :(得分:0)
a)也许他们的意思是将其与链接/加载时间分配进行对比,例如全局变量,常量和static
数据。或许它们意味着将它与堆栈分配进行对比,例如alloca
系列。
b)他们可能会注意到你不应该用C ++ new
分配内存,然后将该内存的所有权传递给可以free()
的库例程。所以从这个意义上讲,分配的结果是特定于语言的。
c)使用C ++ new
和delete
。您必须假设MSVC运行时中的基础C ++分配器与C样式系统调用一样快(如果不相同)。请记住,new
和delete
不仅可以分配和释放内存。它们不能完全替代malloc
和free
或其他C风格的分配器。