• Linux下C程序的存储空间布局


    一个程序本质上都是由 BSS 段、data段、text段三个组成的。可以看到一个可执行程序在存储(没有调入内存)时分为代码段、数据区和未初始化数据区三部分。

    • BSS段(未初始化数据区):在采用段式内存管理的架构中,BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。
    • 数据段:在采用段式内存管理的架构中,数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
    • 代码段:在采用段式内存管理的架构中,代码段(text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

    程序编译后生成的目标文件至少含有这三个段,这三个段的大致结构图如下所示:

    text段和data段在编译时已经分配了空间,而BSS段并不占用可执行文件的大小,它是由链接器来获取内存的
        bss段(未进行初始化的数据)的内容并不存放在磁盘上的程序文件中。其原因是内核在程序开始运行前将它们设置为0。需要存放在程序文件中的只有正文段和初始化数据段。
        data段(已经初始化的数据)则为数据分配空间,数据保存到目标文件中。

    数据段包含经过初始化的全局变量以及它们的值。BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段的后面。当这个内存进入程序的地址空间后全部清零。包含数据段和BSS段的整个区段此时通常称为数据区。

        可执行程序在运行时又多出两个区域:栈区和堆区。
        (4)栈区:由编译器自动释放,存放函数的参数值、局部变量等。每当一个函数被调用时,该函数的返回类型和一些调用的信息被存放到栈中。然后这个被调用的 函数再为他的自动变量和临时变量在栈上分配空间。每调用一个函数一个新的栈就会被使用。栈区是从高地址位向低地址位增长的,是一块连续的内存区域,最大容 量是由系统预先定义好的,申请的栈空间超过这个界限时会提示溢出,用户能从栈中获取的空间较小。
        (5)堆区:用于动态分配内存,位于BSS和栈中间的地址区域。由程序员申请分配和释放。堆是从低地址位向高地址位增长,采用链式存储结构。频繁的 malloc/free造成内存空间的不连续,产生碎片。当申请堆空间时库函数是按照一定的算法搜索可用的足够大的空间。因此堆的效率比栈要低的多。

    下图将体现c的源文件对应存储空间:

    此时程序还没有被放入内存,只是在硬盘存储的情况,此时bss并未占用空间。bss在链接的时候被获得内存空间。

    下图表示程序运行,即程序在内存时的存储布局:

     

     

     

    //main.c  
    int a = 0; //全局初始化区  
    char *p1; //全局未初始化区  
      
    main()  
    {  
        static int c =0//全局(静态)初始化区  
        int b; //
        char s[] = "abc"; //
        char *p2; //
        char *p3 = "123456"; //"123456"在常量区,p3在栈上。  
        p1 = (char *)malloc(10);  
        p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。  
    }

     

     

  • 相关阅读:
    列表的内置方法
    oracle安装教程
    大二暑假假期周进度01
    win 10安装Linux虚拟机教程
    需求工程——软件建模与分析阅读笔记05
    网络爬虫阅读笔记01
    Java 测试连接Oracle数据库是否成功,ojdbc7.jar包下载
    河北创新年报统计平台系统整体界面展示,与数据下钻
    java 三大框架 struct2部分 实现增删该查操作
    itextsharp生成pdf
  • 原文地址:https://www.cnblogs.com/LUO77/p/5853534.html
Copyright © 2020-2023  润新知