进程地址空间

2022/2/27 7:28:17

本文主要是介绍进程地址空间,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

我们使用编译器所看到的内存地址,全部都是虚拟地址!

例如:

  int num=0;
  cout<<&num<<endl;

这时输出的内容就是虚拟地址

再如:
在这里插入图片描述
(Linux下程序运行结果如下,其他环境可能有差别)
在这里插入图片描述
解释:

这个程序有一个全局的变量 g_val=0

fork创建子进程之后,子进程中修改了g_val=100

父进程之后读取g_val的值还是0,而且父子进程输出g_val的地址是一样的

一个物理地址的内容是不可能是两个值,我们编译器看到的地址是虚拟地址。

操作系统负责将 虚拟地址 转化成 物理地址 。物理地址,用户一概看不到,由操作系统统一管理。

进程虚拟空间:

在这里插入图片描述
各个数据节存放的数据类型介绍如下:

(1) 代码段(.text): 也称文本段,由编译器产生,存放程序的二进制机器码和只读数据,比如程序的可执行指令。.text 段是只读的,且大小在运行时是固定的。任何尝试向.text段写入信息的都会导致段错误。

(2) 数据段: 用于存储全局变量等。其主要包括:

①已初始化的数据段(.data): 存放全局和静态的已初始化变量。本节占用的内存大小在运行时也是固定的,标记为只读。

②末初始化的数据段(.bss): 存放全局和静态的未初始化变量。本节占用的内存大小运行时也是固定的。该段应标记为可读可写,但不可执行。

(3)堆(heap): 用来存储程序运行时动态分配的变量。堆内存的分配释放一般由程序控制,其分配由 new(),malloc() 等实时内存分配函数实现。如果程序没有释放该部分内存,则在程序结束后由系统回收。

(4)栈stack):用来存储函数调用信息和临时变量的数据结构,程序运行时根据需要分配,在不需要时自动清除。

(5)环境变量/命令行参数: 用于存储进程运行时可能用到的系统变量的副本。例如,运行时进程可访问的路径、shell 名称等。该节是可读可写的。除此之外,命令行参数也存储在该区域。

在默认情况下Windows系统将高地址的2 GB空间分配给操作系统(也可配置1 GB),而Linux系统将高地址的1 GB空间分配给内核。这些分配给内核的空间叫内核空间,用户不可访问,用户使用剩下的空间称为用户空间。

文章开始部分的程序,g_val是已初始化的全局变量,存在 .data 部分
虚拟的进程地址通过页表映射到了物理内存的不同地方
在这里插入图片描述
(本文虚拟地址部分摘自 《网络安全》张立江)



这篇关于进程地址空间的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程