CRT堆
实验环境: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堆的更多相关文章
- [老文章搬家] [翻译] 深入解析win32 crt 调试堆
09 年翻译的东西. 原文见: http://www.nobugs.org/developer/win32/debug_crt_heap.html 在DeviceStudio的Debug编译模式下, ...
- [c++]堆和栈的区别
堆和栈的区别一.预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构 ...
- windows程序员进阶系列:《软件调试》之堆 (一)
windows程序员进阶系列:<软件调试>之堆 (一) 堆是软件在运行时动态申请内存空间的主要途径.从堆上申请来的空间需要程序员自己申请和释放,且申请和释放操作必须绝对匹配.忘记释放或者多 ...
- 堆和栈的区别【zz】
一.预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈.2. ...
- VC使用CRT调试功能来检测内存泄漏
信息来源:csdn C/C++ 编程语言的最强大功能之一便是其动态分配和释放内存,但是中国有句古话:“最大的长处也可能成为最大的弱点”,那么 C/C++ 应用程序正好印证了这句话.在 C/C+ ...
- windows程序员进阶系列:《软件调试》之Win32堆的调试支持
Win32堆的调试支持 为了帮助程序员及时发现堆中的问题,堆管理器提供了以下功能来辅助调试. 1:堆尾检查(Heap Tail Check) HTC,在堆尾添加额外的标记信息,用于检测堆块是否溢出. ...
- 转:win32下的堆管理系统
转:https://bbs.pediy.com/thread-224136.htm 准备刷漏洞战争中的堆溢出部分,但是对于堆的了解较少,在这里记录一下关于堆的学习记录,有错误请各位大大拍砖 参考: & ...
- Windows内存小结
以前写过一篇理解程序内存, 当时主要是针对用户态,下面再稍微深入一点: 我们以32位程序为例(不启用AWE), 总共4G虚拟空间,其中低2G属于用户态, 高2G属于操作系统内核, 每个程序都有自己的低 ...
- java\c程序的内存分配
JAVA 文件编译执行与虚拟机(JVM)介绍 Java 虚拟机(JVM)是可运行Java代码的假想计算机.只要根据JVM规格描述将解释器移植到特定的计算机上,就能保证经过编译的任何Java代码能够在该 ...
随机推荐
- MongoDB数据模型(一)
原文地址 一.数据模型介绍 MongoDB中的数据有着灵活的架构.与SQL数据库不同,因为SQL数据库必须先定义表结构,然后才能向其中插入数据,而MongoDB的集合不强制任何文档结构.这个灵活性方便 ...
- 大D实例化model-->调用自定义类方法,大M调用原声model方法
class ContactsModel extends Model{ public function addxxx(){ } } $conmodel = D('contacts','Model'); ...
- IdentityDbContext类源码
Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs 源码: 其中涉及到用户信息表.用户角色表的相关操作. using Syst ...
- Docker技术学习
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://sofar.blog.51cto.com/353572/1598249 貌似Doc ...
- mysql建表设置两个默认CURRENT_TIMESTAMP的技巧
转载:http://blog.163.com/user_zhaopeng/blog/static/166022708201252323942430/ 业务场景: 例如用户表,我们需要建一个字段是创 ...
- MYSQL:SQL中Group By的使用
SQL中Group By的使用 1.概述 2.原始表 3.简单Group By 4.Group By 和 Order By 5.Group By中Select指定的字段限制 6.Group By ...
- bzoj1977
1977: [BeiJing2010组队]次小生成树 Tree Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 3001 Solved: 751[Su ...
- JS获取网页中HTML元素的几种方法分析
getElementById getElementsByName getElementsByTagName 大概介绍 getElementById ,getElementsByName ,getEle ...
- int与byte的区别
Java中涉及byte.short和char类型的运算操作首先会把这些值转换为int类型,然后对int类型值进行运算,最后得到int类型的结果.因此,如果把两个byte类型值相加,最后会得到一个int ...
- LeetCode OJ 202. Happy Number
Write an algorithm to determine if a number is "happy". A happy number is a number defined ...