2

根据这篇文章,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

4 回答 4

9

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

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

一个潜在的缺点是,当进程堆损坏时,更难以生成有意义的诊断或完全关闭,Windows 也使用该堆。并且代码中的内存损坏会破坏操作系统调用的稳定性,这种调用不涉及内核调用,在那里一切皆有可能。我也可以想象一个安全风险,我假设一旦他们对安全的 CRT 增强感到满意,就会做出这个选择。

于 2013-09-23T17:31:06.977 回答
1

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

但是,我不清楚(不幸的是,没有项目文件)哪些 CRT 版本使用 smalheap.c,哪些 CRT 版本使用 heapinit.c。

于 2013-09-23T17:21:23.277 回答
1

FWIW,除了汉斯的回答。我已经设法通过以下选项强制 VS2012 CRT 使用私有堆(不幸的是,带有链接器警告):

  1. 在 C/C++/Code Generation/Runtime Library 中切换到 /MT(即使用静态 c-runtime 链接)
  2. 添加smalheap.obj到链接器/输入/附加依赖项
  3. 添加/FORCE:MULTIPLE到链接器/命令行/附加选项(以避免 _heap_init 和朋友的 LNK2005 错误)

恕我直言,很遗憾我们没有私有堆和 c-runtime 动态 dll 的选项。这将有助于解决 3rd 方库中的内存泄漏问题。在长时间运行的过程中,您可以卸载所有内容并再次加载。

于 2016-05-18T08:07:22.607 回答
0

在文章中,CRT 创建了自己的私有堆,它位于 Windows 堆的顶部

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

于 2013-09-23T10:23:49.593 回答