C/C++的内存布局

来源:互联网 发布:js 滑动选择插件 编辑:程序博客网 时间:2024/06/05 08:51
C/C++的内存布局通常有两种说法:一种是堆、栈、全局/静态存储区、自由存储区和常量存储区。另外一种是堆、栈、全局/静态存储区、字符串常量区和代码区。其实更详细准确的说法如下:

1 .rodata段:存放只读数据,比如printf语句中的格式字符串和开关语句的跳转表。也就是你所说的常量区。
例如,全局作用域中的 const int ival = 10,ival存放在.rodata段
再如,函数局部作用域中的printf("Hello world %d\n", c);语句中的格式字符串"Hello world %d\n",也存放在.rodata段

2 .text段:存放已编译程序的机器代码。

注意:程序加载运行时,.rodata段和.text段通常合并到一个Segment(Text Segment)中,操作系统将这个Segment的页面只读保护起来,防止意外的改写。

3 .data段:存放已初始化的全局变量。而局部变量在运行时保存在栈中,既不出现在.data段,也不出现在.bss段中。就是你所说的全局区。
例如:全局作用域中的int ival = 10,static int a = 30,以及局部作用域中的static int b = 30,这3个变量均存放在.data段中。注意,局部作用域中的static变量的生命周期和其余栈变量的生命周期是不同的。

4 .bss段:存放未初始化的全局变量。在目标文件中这个段不占据实际的空间,它仅仅是一个占位符,在加载时这个段用0填充。目标文件区分初始化和未初始化变量是为了空间效率:在目标文件中,未初始化变量不需要占据任何实际的磁盘空间。全局变量如果不初始化则初值为0,同理可以推断,static变量(不管是函数里的还是函数外的)如果不初始化则初值也是0,也分配在.bss段。
例如,全局作用域中的int ival; ival显然存放在.bss段


注意:.data和.bss在加载时合并到一个Segment(Data Segment)中,这个Segment是可读可写的。

5. 栈:函数的参数和局部变量是分配在栈上(但不包括static声明的变量)。在函数被调用时,栈用来传递参数和返回值。由于栈的后进先出特点,所以栈特别方便用来保存/恢复调用现场。

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


学习资料参考于:
https://www.zhihu.com/question/26224882/answer/32384814
0 0
原创粉丝点击