实验环境:win764位旗舰版、VS2010旗舰版

	每个进程都有一个默认堆,在进程初始化的时候会创建这个默认堆,可以通过GetProcessHeap()获取默认堆的句柄。使用CRT时,也会有一个CRT堆,VS项目属性 ~ C/C++ ~ 代码生成 ~ 运行库,如果选择多线程DLL,则CRT堆初始化在DLL中,如果选择多线程,则会在进入_tmain函数之前。

运行库连接方式设置:

CRT堆初始化:

位于VS目录Microsoft Visual Studio 10.0\VC\crt\src\heapinit.c文件中有一个_heap_init函数,可以设置断点查看CRT堆初始化过程。

int __cdecl _heap_init (void)
{
ULONG HeapType = 2; // Initialize the "big-block" heap first.
if ( (_crtheap = HeapCreate(0, BYTES_PER_PAGE, 0)) == NULL )
return 0; #ifdef _WIN64
// Enable the Low Fragmentation Heap by default on Windows XP and
// Windows Server 2003. It's the 8 byte overhead heap, and has
// generally better performance charateristics than standard heap,
// particularly for apps that perform lots of small allocations. if (LOBYTE(GetVersion()) < 6)
{
HeapSetInformation(_crtheap, HeapCompatibilityInformation,
&HeapType, sizeof(HeapType));
}
#endif /* _WIN64 */
return 1;
}

注意:这里调用HeapCreate函数的第一个参数使用0,而没有使用HEAP_NO_SERIALIZE标志,则表示对堆的访问时独占的,即默认情况下使用new和delete是线程安全的。

c++使用new是在CRT堆上分配内存:

位于VS目录Microsoft Visual Studio 10.0\VC\crt\src\malloc.c文件中有一个_heap_alloc函数

__forceinline void * __cdecl _heap_alloc (size_t size)

{

    if (_crtheap == 0) {
_FF_MSGBANNER(); /* write run-time error banner */
_NMSG_WRITE(_RT_CRT_NOTINIT); /* write message */
__crtExitProcess(255); /* normally _exit(255) */
} return HeapAlloc(_crtheap, 0, size ? size : 1);
}
	经常听到高手说,最好不要跨模块new和delete,否则将会出现严重的错误(堆被破坏)。例如在DLL中使用new分配一块内存,让后在EXE中使用delete释放这块内存,有可能堆会被破坏,原因是,如果EXE和DLL都是用静态库的方式链接运行时库,此时EXE和DLL各自将有一个CRT堆,在一个堆上分配内存,让后再另一个堆上释放内存是肯定会发生错误的。如果EXE和DLL都是用动态库的方式链接运行时库,他们使用的是同一个CRT堆,则不会发错误。

CRT堆的更多相关文章

  1. [老文章搬家] [翻译] 深入解析win32 crt 调试堆

    09 年翻译的东西. 原文见:  http://www.nobugs.org/developer/win32/debug_crt_heap.html 在DeviceStudio的Debug编译模式下, ...

  2. [c++]堆和栈的区别

    堆和栈的区别一.预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构 ...

  3. windows程序员进阶系列:《软件调试》之堆 (一)

    windows程序员进阶系列:<软件调试>之堆 (一) 堆是软件在运行时动态申请内存空间的主要途径.从堆上申请来的空间需要程序员自己申请和释放,且申请和释放操作必须绝对匹配.忘记释放或者多 ...

  4. 堆和栈的区别【zz】

    一.预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.2. ...

  5. VC使用CRT调试功能来检测内存泄漏

    信息来源:csdn     C/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:“最大的长处也可能成为最大的弱点”,那么 C/C++ 应用程序正好印证了这句话.在 C/C+ ...

  6. windows程序员进阶系列:《软件调试》之Win32堆的调试支持

    Win32堆的调试支持 为了帮助程序员及时发现堆中的问题,堆管理器提供了以下功能来辅助调试. 1:堆尾检查(Heap Tail Check) HTC,在堆尾添加额外的标记信息,用于检测堆块是否溢出. ...

  7. 转:win32下的堆管理系统

    转:https://bbs.pediy.com/thread-224136.htm 准备刷漏洞战争中的堆溢出部分,但是对于堆的了解较少,在这里记录一下关于堆的学习记录,有错误请各位大大拍砖 参考: & ...

  8. Windows内存小结

    以前写过一篇理解程序内存, 当时主要是针对用户态,下面再稍微深入一点: 我们以32位程序为例(不启用AWE), 总共4G虚拟空间,其中低2G属于用户态, 高2G属于操作系统内核, 每个程序都有自己的低 ...

  9. java\c程序的内存分配

    JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...

随机推荐

  1. poj_1743_Musical Theme(后缀数组)

    题目链接:poj_1743_Musical Theme 题意: 给你一串数字,让你找最长的变化相同不重叠的子串,至少长度为5 题解: 处理数据后用后缀数组加二分答案,然后用height数组check答 ...

  2. FZU 1893 内存管理 模拟

    比赛的时候队友要做这道题…… 他没做出来自己也被误导了…… 也算是个教训 自己还是要有自己的思路…… 又是模拟题…… 网上都是用vector做的 我最近才会stl 怎么会用那么高大上的的东西…… 强力 ...

  3. C++中构造函数或析构函数定义为private

    转自:http://www.blogjava.net/fhtdy2004/archive/2009/05/30/278971.html 很多情况下要求当前的程序中只有一个object.例如一个程序只有 ...

  4. erlang四大behaviour之一gen_server

      来源:http://www.cnblogs.com/puputu/articles/1701017.html erlang程序设计里面有个设计原则就是把你的进程构造成树,把共用代码提出来,特定功能 ...

  5. Spring测试

    测试类添加两个注解 @RunWith(SpringJUnit4ClassRunner.class)和@ContextConfiguration(locations = "classpath: ...

  6. ajax 假上传文件

    1. <form name="certForm" id="certForm" method="post" action="x ...

  7. webstorm2016.2.4激活码

    测试日期:2016.11.07 webstorm版本:2016.2.4 系统环境:MacOS(windows环境应该也行) 激活码如下: 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0 ...

  8. android中对Bitmap图片设置任意角为圆角

    http://blog.csdn.net/l448288137/article/details/48276681 最近项目开发中使用到了圆角图片,网上找到的圆角图片控件大多比较死板,只可以全圆角.其中 ...

  9. 2.Perl 多线程:Threads(线程返回值)

    use warnings; use strict; use threads; sub TEST{ print "Hello, World!\n"; 'a'/); } #返回列表方法 ...

  10. 工作线程基类TaskSvc

    工作线程基类TaskSvc 前端时间用ACE写代码,发ACE_Task确实好用.不但能提供数量一定的线程,还能够让这些继承的线程函数自由访问子类的private和protected变量.此外,ACE_ ...