• CRT堆


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

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

    运行库连接方式设置:

     

    CRT堆初始化:

    位于VS目录Microsoft Visual Studio 10.0VCcrtsrcheapinit.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.0VCcrtsrcmalloc.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堆,则不会发错误。
  • 相关阅读:
    mybatis动态sql中的两个内置参数(_parameter和_databaseId)
    Vue.js项目部署在Tomcat服务器上
    Vue2.0 + ElementUI的+ PageHelper实现的表格分页
    mybatis中使用mysql的模糊查询字符串拼接(like)
    C++循环链表解决约瑟夫环问题
    Nginx源码分析-ngx_module_s结构体
    设计模式(一)工厂模式Factory(创建型)(转)
    网络编程--套接字选项(一)
    Linux阵列 RAID详解 (转)
    HDFS RAID实现方案(转)
  • 原文地址:https://www.cnblogs.com/dongc/p/5225111.html
Copyright © 2020-2023  润新知