C程序中的内存分布

转载来源:Link

一个典型的C程序的内存分布由以下几个部分组成:

  1. Text segment,或代码段
  2. Data segment,或已初始化数据段(Initialized data segment)
  3. BSS segment,或未初始化数据段(Uninitialized data segment)
  4. 栈(Stack)
  5. 堆(Heap)

 

1. Text段

  Text段通常也称为代码段,由可执行指令构成,是程序在目标文件或内存中的一部分,Text段通常放在栈或堆的下面,以防止堆栈溢出篡改其数据。

  通常情况下,Text段是可共享的,对于需要频繁调用的程序,其在内存中只需要一份拷贝即可,如文本编辑器、C编译器、Shell等,因此text段通常设为只读以防止程序的突发性的修改。

 

2. Data 段(已初始化数据段

  已初始化数据段,通常简单称作数据段,数据段占据程序虚拟地址空间的一部分,内部包括全局变量、静态变量(程序负责初始化这些变量)。需注意的是,数据段不是只读的,在运行时变量值是可以变动的。数据段还可以更细的分为初始化只读区以及初始化可读写区。

  举例:全局字符串 char s[] = “hello world”,全局变量 int debug=1,静态变量 static int i = 10 存储在初始化可读写区;另一种情况下,const char* string = “hello world”,字符串“hello world”存储在初始化只读区,string指针则存在初始化可读写区。

 

3. BSS段(未初始化数据段

  未初始化数据段,通常称作BSS段,名字来源于古老的汇编操作符命名 “block started by symbol”,段内的数据在程序开始执行之前被内核初始化为0值,通常开始于已初始化数据段的末尾处。段内包含初始化为0的全局变量/静态变量以及源码中未显示进行初始化的变量。

  举例:变量 static int i;  全局变量 int j;  包含在BBS段中。

 

4. 栈

  栈与堆是相互毗邻的,并且生长方向相反;当栈指针触及到堆指针位置,意味着栈空间已经被耗尽(如今地址空间越来越大,及虚拟内存技术发展,栈与堆可能放置在内存的任何地方,但生长方向依然还是相向的)。

  栈区域包含一个LIFO结构的程序栈,其通常放置在内存的高地址处,在x86架构中,栈朝地址0方向生长,在其它架构也可能朝着相反的方向生长。栈指针寄存器跟踪栈顶位置,每当有数值被压入栈中,栈顶指针会被调整,在一个函数的调用过程中,压入的一系列数值被称作“栈帧”,栈帧至少包含一个返回地址。

  栈存储着自动变量以及每次函数调用时保存的信息,每当函数被调用时,返回地址以及调用者的上下文环境例如一些机器寄存器都存储在栈中,新的被调用函数此时会在栈上重新分配自动/临时变量,这就是递归函数的工作原理。每当函数递归调用自己时,都会使用新的栈帧,因此当前函数实体内的栈帧内的变量不会影响另外一个函数实体内的变量。

 

5. 堆

  堆通常用作动态内存分配,堆空间起始于BSS段的末尾,并向高地址处生长,堆空间通常由malloc, realloc 及 free管理,这些接口可能再使用brk/sbrk系统调用来调整大小,在一个进程中,堆空间被进程内所有的共享库及动态加载模块所共享。

 

参考:

https://www.cnblogs.com/miaoxiong/p/11021827.html

https://blog.csdn.net/DLUTBruceZhang/article/details/9080157?utm_source=copy

posted on 2020-05-16 13:52  泣血  阅读(325)  评论(0编辑  收藏  举报

导航