• 侯捷 - C++ Startup 揭密:C++ 程序的生前和死后 (一)


    前言:如何自定Startup code(CRT)
    提问:

    C++进入点是main()吗?
    什么代码比main()更早被执行?
    什么代码在main()结束后才被执行?
    为什么上述代码可以如此行为?
    Heap的结构如何?
    I/O的结构如何?
     在windows环境下,使用VC6进行开发,我们写下以下代码(启动码函数):

    #include
    int MyStartup(void)
    {
        int a=10;
        HANDLE crtHeap=HeapCreate(HEAP_NO_SERIALIZE,0x010,4000*1024);
        int *p=(int*)HeapAlloc(crtHeap,HEAP_ZERO_MEMORY,0X010);
        int i,j;
        
        for(i=0;i<100;i++)
        {
            for(j=0;j<100;j++,p++)
            {
                *p=i*100+(j+1);
            }
        }    
     
        MessageBoxA(NULL,p,"abcd",MB_OK);
        return 0;
    }

    我们的程序将从MyStartup()函数启动,并且不会调用main函数(因为我们没写。。)

    在linux环境下,我们编写了两个函数,使用GCC进行编译:

    $ cat entrypoint.c
     
    int blabla(){ printf("Yes it works!\n"); exit(0); }
    int main(){ printf("not called!\n");}
     
    $ gcc entrypoint.c -e blala    //-e:告诉使用balala函数作为进入点
     
    $ ./a.out
    Yes it works!                 //main函数并没有执行
     

    总结:

    任何的c/c++程序,在main函数之前,有一个启动函数,你的main函数必须由启动码函数调用起来。启动码也是最早执行的函数。

    默认的startup code在哪里,main()生前和死后的call stack
    我们以VC6为例:主要分为9个点来分析:

     
    1.heap_init()——Startup的首要管理工具
    内存块:1.从何处来?2.大小几何?3.回收至何处?

    SBH(Small Block Heap):应付CRT本身以及main进去之后的所有内存(size=1024=1k)。

    如果客户要的区块大小要小于sbh_threshold(size=1016,加上图中的上下的00000131(各占4个字节),1016+8=1024,即1K),将从sbh内部去申请内存。反之,使用HeapAlloc(win提供的API函数),让操作系统提供服务。

    因此,内存小于等于1K的,VC6认为它足够小,它将使用SBH去服务它。反之,若大于1K,将有操作系统那些"池塘"(HeapAlloc等函数)来提供。(内存块从哪里来)

    HeapAlloc:HeapAlloc是Windows提供的API,在进程初始化的时候,系统会在进程的地址空间中创建1M大小的堆,称为默认堆(Default Heap),该大小为默认值,可以通过/HEAP连接器开关进行修改。用户也可以通过HeapCreate创建额外的堆,堆的使用可以更有效的进行内存管理,避免线程同步的开销以及快速的释放内存等。

    我们可以向操作系统(win)要求A这么一大块内存,B这么一大块内存,C这么一大块内存,我们可以根据不同用途从不同的内存块获取。若需要A功能就从A里面拿,若需要B功能就从B里面拿。

    SBH初始化:

    给我一块区域,多大呢?4096(初始值,可弹性增长)。我们把它取名位crtheap。

    heap_init在做初始化呢,申请了16个Headers(可在内存管理章节详细了解)。

    每个Header的内部情况:


    ————————————————
    版权声明:本文为CSDN博主「Jeff_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_40539125/article/details/100631710

  • 相关阅读:
    输入的查询 SQL 语句,是如何执行的?
    【Java】Collections.shuffle 洗牌方法,随机重排序一组元素
    通过 JFR 与日志深入探索 JVM - 调试 JVM 的工具 WhiteBox API
    424. 替换后的最长重复字符 ●●
    office2019如何自定义安装位置?
    红细胞膜包裹铜纳米颗粒/红细胞膜修饰普鲁兰纳米粒子/载磁性碳/黑磷量子点细胞膜制备
    雷达设备(贪心,区间选点)
    基于SSM的学生事务处理系统设计与实现
    LeetCode_54_螺旋矩阵
    VR全景如何应用在房产行业,VR看房有哪些优势
  • 原文地址:https://blog.csdn.net/u012294613/article/details/126876653