为什么_get_heap_handle等于GetProcessHeap?

时间:2013-09-23 09:28:48

标签: winapi msvcrt

根据这个article,CRT使用单独的堆(它是私有堆吗?),但是这个小例子显示 CRT堆默认堆是相同的:

HANDLE heaps[64];
DWORD heapCount = GetProcessHeaps(64, heaps);    
for (int i = 0; i<heapCount; i++)
    printf("heap %d : [0x%x]\n", i, heaps[i]);
printf("crt heap[0x%x], default heap[0x%x]\n", _get_heap_handle(), GetProcessHeap());

在哪些情况下 GetProcessHeap _get_heap_handle 会返回不同的句柄?

//使用VS2012(平台工具集v110)编译

4 个答案:

答案 0 :(得分:9)

这是VS2012的新功能,CRT现在使用默认进程堆来分配。以前的版本总是创建自己的堆。

使用默认堆的一个显着优点是,与DLL中的代码互操作将更容易,它可以显着减少必须使用具有自己的CRT链接的副本的DLL的麻烦。假设副本当然也是2012+年份。

潜在的缺点是,当进程堆损坏时,生成有意义的诊断或干净关闭会更加困难,Windows也会使用该堆。代码中的内存损坏可能会破坏OS调用的稳定性,这种调用不涉及内核调用,那里可能发生任何事情。我可以想象一下安全风险,我认为一旦他们对安全的CRT增强感到满意就做出了这个选择。

答案 1 :(得分:1)

C运行时源(malloc.c)显示所有CRT分配都是从_crtheap创建的(这是_get_heap_handle返回的内容)。在heapinit.c中,_crtheap设置为GetProcessHeap。在smalheap.c中有一个单独的分配例程,它将_crtheap设置为HeapCreate

然而,我不清楚(遗憾的是没有项目文件)哪些CRT版本使用smalheap.c以及哪些CRT版本使用heapinit.c。

答案 2 :(得分:1)

除了汉斯的答案之外,还有其他人。我已设法强制VS2012 CRT使用具有以下选项的私有堆(不幸的是链接器警告):

  1. 在C / C ++ /代码生成/运行时库中切换到/ MT(即使用静态c运行时链接)
  2. smalheap.obj添加到链接器/输入/附加依赖项
  3. /FORCE:MULTIPLE添加到链接器/命令行/其他选项(以避免_heap_init和朋友出现LNK2005错误)
  4. 恕我直言,很遗憾我们没有私有堆和c-runtime动态dll的选项。这将有助于第三方库中的内存泄漏。如果是长时间运行的过程,您可以卸载所有内容并重新加载。

答案 3 :(得分:0)

从文章中, CRT创建自己的私有堆,它驻留在Windows堆的顶部上。

CRT从相同的默认进程堆分配/取消分配。私有意味着对象的所有内容都是CRT专用的。