关于内存分配和C ++

时间:2010-06-13 13:42:25

标签: c++ visual-studio visual-c++

我引用MSDN http://msdn.microsoft.com/en-us/library/aa366533(VS.85).aspx

  

malloc函数有   运行时的缺点   依赖。新的运营商有   编译器的缺点   依赖和语言依赖。

现在有问题的人:

a)我们的意思是malloc与运行时有关吗?什么样的动态内存分配函数可以独立于运行时?这句话听起来很奇怪。

b)新的语言依赖?当然应该是对的? HeapAlloc,LocalAlloc等语言是否独立?

c)从纯粹的性能角度来看,MSVC提供的例程更可取吗?

Arpan

4 个答案:

答案 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)

哇,这是一个好奇的陈述,出现在文档中,没有附带的解释。它可能是C ++推出时的延续吗?我只能猜测你问题的答案:

a)也许他们的意思是将其与链接/加载时间分配进行对比,例如全局变量,常量和static数据。或许它们意味着将它与堆栈分配进行对比,例如alloca系列。

b)他们可能会注意到你不应该用C ++ new分配内存,然后将该内存的所有权传递给可以free()的库例程。所以从这个意义上讲,分配的结果是特定于语言的。

c)使用C ++ newdelete。您必须假设MSVC运行时中的基础C ++分配器与C样式系统调用一样快(如果不相同)。请记住,newdelete不仅可以分配和释放内存。它们不能完全替代mallocfree或其他C风格的分配器。