根据这个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)编译
答案 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)
smalheap.obj
添加到链接器/输入/附加依赖项/FORCE:MULTIPLE
添加到链接器/命令行/其他选项(以避免_heap_init和朋友出现LNK2005错误)恕我直言,很遗憾我们没有私有堆和c-runtime动态dll的选项。这将有助于第三方库中的内存泄漏。如果是长时间运行的过程,您可以卸载所有内容并重新加载。
答案 3 :(得分:0)
从文章中, CRT创建自己的私有堆,它驻留在Windows堆的顶部上。
CRT从相同的默认进程堆分配/取消分配。私有意味着对象的所有内容都是CRT专用的。