C 程序的存储空间记录

  • 一直以来,我们只是单纯的去运行执行 C 程序,并没有关心这个可执行文件里面包含着什么东西。

  • 参考UNIX 环境高级编程 7.6,记录C程序的存储空间布局。


* ### C程序由 正文段,初始化数据段,非初始化数据段,栈,堆组成 * ### 正文段,初始化数据段,非初始化数据段(bss) ``` 正文段:CPU执行的机器指令部分。 ``` ``` 初始化数据段:通常将此段称为数据段,包含了程序中需明确的赋初始值的变量。 比如说,c 程序中出现在任何函数之外的声明。 静态变量都在 初始化数据段: static int i = 1000; 全局变量 int test = 100; ``` ``` 非初始化数据段: 一般我们称为 bss 段,这一名称来源于早期的汇编运算符,意思是 block started by symbol , 在程序开始执行之前,kernel 会将这个 bss 段中的数据全部初始化为0或者是空指针。 比如说: 未初始化局部变量: static int chen; 全局变量: ing test1[100]; ``` * ### 写一段简单的代码,看一下上面的内存分布, 名字是test.c: ```c #include
void test(void)                                                                 
{                                                                               
    printf("This is test function\n");                                          
}                                                                               
                                                                            
int main(void)                                                                  
{                                                                               
    printf(" This is main function\n");                                         
    return 0;                                                                   
} 
```c
    看一下这个代码生成可执行文件的各个内存分布:
    sbc_7109_454_pdk3@aplex:~/test/c_program$ gcc test.c -o test
    sbc_7109_454_pdk3@aplex:~/test/c_program$ size test
       text	   data	    bss	    dec	    hex	filename
       1229	    552	      8	   1789	    6fd	test  
    然后,我们在里面加一个局部变量,全局变量:
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817113549365-425031064.png)
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817113911240-769225067.png)
    在看一下局部静态变量:
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817114334756-1509640442.png)
  • 栈和堆

    在执行程序前,我们能看到的是上面的 非初始化数据段以及初始化数据段和正文段,在执行了程序后,我们还能看到栈和堆。
    栈:自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次调用函数时,其返回地址以及调用者的环境信息,都存放在栈中。然后,最近被调用的函数在栈上为其自动和临时变量分配存储空间。通过以这种方式使用栈,可以递归调用C函数,递归函数每次调用自身时,就使用一个新的栈帧,因此一个函数调用实例中的变量集不会影响另一个函数调用实例中的变量。
    局部变量也是存放在栈区。
    堆:动态内存分配。堆处于非初始化数据段和栈之间。
  • 代码 test.c:

    #include <stdio.h>                                                              
    #include <stdlib.h>                                                             
    #include <string.h>                                                             
                                                                                
    void test(void)                                                                 
    {                                                                               
        printf("This is test function\n");                                          
    }                                                                               
                                                                                
    int test1 = 100;                                                                
    int test2;                                                                      
                                                                                
    int main(void)                                                                  
    {                                                                               
        int a;                                                                      
        static int b = 100;                                                         
        static int c;                                                               
        char *test3;                                                                
                                                                                
        test3 = (char *)malloc(sizeof(char) * 10);                                  
                                                                                
        int *pa = &a, *pb = &b, *pc = &c, *ptest1 = &test1, *ptest2 = &test2;          
        printf("桟:pa = %p\n", pa);   // 桟  stack                                 
        printf("堆:test3 = %p\n", test3);  // 堆 heap                              
        printf("bss: ptest2 = %p\n", ptest2); // 未初始化的数据区                   
        printf("bss: pc = %p\n", pc);   // 未初始化的数据区  bss                    
        printf("data: ptest1 = %p\n", ptest1);  // 初始化的数据区                   
        printf("data: pb = %p\n", pb);   // 初始化的数据区                          
                                                                                
        free(test3);                                                                
                                                                                
        return 0;                                                                   
    } 
![](http://images2017.cnblogs.com/blog/991711/201708/991711-20170817131823225-423244804.png)
  • 空间分配如下图所示:

posted @ 2017-08-17 11:16  陈富林  阅读(273)  评论(0编辑  收藏  举报