C_CPP进程内存空间分布

内存分区

内存分布分为5个部分,从高地址到低地址依次为栈区(stack),堆区(heap),未初始化数据段(uninitialized data),初始化数据段(initialize data)和代码段(text)。

有些文档也把初始化的数据段和未初始化的数据段合称全局区。

1. 文本段--只读、共享,操作系统管理

文本段也叫代码段,是对象文件或内存中程序的一部分,其中包含可执行指令。文本段在堆栈的下面,是防止堆栈溢出覆盖它。

通常代码段是共享的,对于经常执行的程序,只有一个副本需要存储在内存中;代码段是只读的,以防止程序以外修改指令。

2. 初始化的数据段

通常称为数据段,是程序的虚拟地址空间的一部分,它包含程序员初始化的全局变量和静态变量以及常量,可以进一步划分为只读区域和读写区域。

例如,C中的char=“hello world”的全局字符串,以及main(例如全局)之外的int debug=1这样的C语句,将被存储在初始的读写区域中。

而像const char字符串=“hello world”这样的全局C语句常量字符串文字“hello world”被存储在初始化的只读区域中,并在初始化的读写区域中存储字符指针变量字符串。

3. 未初始化的数据段--内核初始化为0

通常称为bss段,这个段的数据在程序开始之前有内核初始化为0,包含所有初始化为0和没有显示初始化的全局变量和静态变量。

这个段在程序开始之前由内核初始化为全0,所以不在可执行文件中占用位置,可减少可执行文件体积。

4. 堆--程序员管理

堆是动态内存分配通常发生的部分。内存分配由低到高,分配方式类似于数据结构的链表。堆区域从BSS段的末尾开始,并从那里逐渐增加到更大的地址。

堆是由程序员自己分配的,或程序结束后由操作系统自动回收。堆区域由所有共享库和进程中动态加载的模块共享。(malloc和new从堆区分配内存)

5. 栈--编译器分配管理

存放自动变量,以及函数调用时保存的信息。每当进行函数调用时,函数的实参和返回地址以及调用者的上下文环境会被存放在栈中;栈区由编译器自动分配,从高地址向低地址扩展。

在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

内存分区的意义

不同区域存放的数据,赋予不同的生命周期,给编程更大的灵活性。

相关文章:

  • 2022-12-23
  • 2021-08-02
  • 2021-12-13
  • 2021-08-14
  • 2021-10-19
  • 2022-12-23
  • 2021-08-05
  • 2021-07-25
猜你喜欢
  • 2021-07-30
  • 2022-12-23
  • 2021-10-04
  • 2021-05-18
  • 2022-12-23
  • 2021-10-28
相关资源
相似解决方案