vlambda博客
学习文章列表

C语言程序的内存布局

我们编写的C程序属于编译型语言,需要将编写好的C程序经过编译、汇编、链接,最后生成二进制机器码,这个可以被操作系统识别,并加载到内存中执行。经过编译后的C程序由主要由以下几部分组成:BSS 段、data段、text段。

  • BSS段

BSS段通常用来存放程序中未初始化的全局变量,属于静态内存分配。
  • data段

data段通常用来存放程序中已初始化的全局变量,属于静态内存分配。
  • text段

text段通常用来存放程序执行代码的区域,这部分大小在程序运行时已经确定,在内存区域内属于只读。
编译后,生成的目标文件至少含有三段,则三段结构如下图所示。

其中:

text即为代码段,为只读

bss段包含程序中未初始化的全局变量和static变量

data段包含三个部分:heap(堆)、stack(栈)和静态数据区。

  • 堆(heap)

堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
  • 栈 (stack)

栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
  • 静态数据区

存放的是程序中已初始化的全局变量、静态变量和常量。

text和data段都在可运行文件里(在嵌入式系统里通常是固化在镜像文件里)。由系统从可运行文件里载入;而BSS段不在可运行文件里,由系统初始化。

bbs段仅仅保存没有值的变量。所以其实它并不需要保存这些变量的映像。执行时所需要的BSS段大小记录在目标文件里,但BSS段并不占领目标文件的不论什么空间。

 1int a = 0//全局初始化区  
2char *p1; //全局未初始化区  
3
4main()  
5{  
6    static int c =0; //全局(静态)初始化区  
7    int b; //栈  
8    char s[] = "abc"//栈  
9    char *p2; //栈  
10    char *p3 = "123456"//"123456\0"在常量区,p3在栈上。  
11    p1 = (char *)malloc(10);  
12    p2 = (char *)malloc(20); //分配的10和20字节的区域就在堆区。  
13