【Linux】程序地址空间

程序地址空间

      • 首先引入地址空间的作用
      • 什么是地址空间
      • 为什么要有地址空间

首先引入地址空间的作用

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 

	int g_val = 100;
  6 int main()
  7 {
  8   pid_t id = fork();
  9   if(id == 0)
 10   {
 11     int cnt = 0;
 12     while(1)
 13     {
 14       printf("I am child,pid : %d,ppid : %d,g_val : %d,&g_val : %p\n",getpid(),getppid(),g_val,&g_val);
 15       cnt++;
 16       sleep(1);
 17       if(cnt == 5)
 18       {
 19         g_val = 200;
 20         printf("child chage g_val 100 -> 200 success\n");
 21       }
 22     }
 23   }
 24   else 
 25   {
 26     //father
 27     while(1)
 28     {                                                                                                                                                
 29 
 30       printf("I am father,pid : %d,ppid : %d,g_val : %d,&g_val : %p\n",getpid(),getppid(),g_val,&g_val);
 31       sleep(1);
 32     }
 33   }
 34   return 0;
 35 }

我们发现,但我们子进程修改全局变量g_val的时候,父进程的g_val没有受到影响,但是他们的地址都是一样的,这是为什么呢?

在这里插入图片描述

由此我们知道,这里的地址绝对不是物理内存的地址,而是虚拟地址(线性地址);并且几乎所有语言,如果有地址的概念,这个地址一定不是物理地址,而是虚拟地址。物理地址是由操作系统保管的。以下我们就开始介绍虚拟内存的作用

什么是地址空间

首先基本了解一下地址空间的排布情况

目前我们先不考虑解析这里的共享区在这里插入图片描述

代码实现验证地址空间的排布

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 int g_val = 100;
  5 int g_unval;
  6 int main(int argc,char *argv[],char *env[])
  7 {
  8   //代码区
  9   printf("code addr:%p\n",main);
 10   //初始化数据
 11   printf("init global addr:%p\n",&g_val);
 12   //未初始化数据
 13   printf("uninit global addr:%p\n",&g_unval);
 14   //堆区
 15   char* heap_mem = (char*)malloc(10);
 16   char* heap_mem1 = (char*)malloc(10);
 17   char* heap_mem2 = (char*)malloc(10);
 18   char* heap_mem3 = (char*)malloc(10);
 19   printf("heap_mem addr:%p\n",heap_mem);
 20   printf("heap_mem1 addr:%p\n",heap_mem1);
 21   printf("heap_mem2 addr:%p\n",heap_mem2);
 22   printf("heap_mem3 addr:%p\n",heap_mem3);
 23 
 24   //栈区
 25   printf("stack addr:%p\n",&heap_mem);
 26   printf("stack addr:%p\n",&heap_mem1);
 27   printf("stack addr:%p\n",&heap_mem2);
 28   printf("stack addr:%p\n",&heap_mem3);
 29 //字面常量
 30   const char *str = "helloworld";
 31   printf("read only string addr: %p\n", str);
 32   
 33   int i,j;
 34   //命令区                                                                                                
 35    for(i = 0 ;i < argc; i++)                                                                                                                                             
 36     {              
 37         printf("argv[%d]: %p\n", i, argv[i]);
 38     }        
 39   
 40  //环境区
 41  for(j = 0;env[j];++j)
 42  {
 43    printf("env[%d] addr:%p\n",j,&env[j]);
 44  }
 45 
 46   
 47   
 48   return 0;
 49 }


在这里插入图片描述

由此可见我们发现我们输入命令后,命令的地址在我们所执行的代码之后,这说明刚创建好这些变量就有了它自己本身的地址,地址程序结束后才打印,要分清前后

接下来我们来认识什么是地址空间
>

这时我们可以利用虚拟地址加映射机制(页表)来正确的讲地址存入物理内存
虚拟地址:不管哪个编译器,只要看到的地址都是虚拟地址,物理地址是操作系统保管的。
每一行代码都进行了编址。故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址
=什么是映射机制?
映射机制可以将虚拟地址转换到物理地址,如果发现虚拟地址会越界或者错误,则就不会抛出,他起到了关键作用
那么映射机制是怎么判断的呢?
在这里插入图片描述
以上就是所描述的社么是地址空间,简单来说它是存储虚拟地址的。

在这里插入图片描述

地址空间和页表(用户级)是每一个进程都单独有一份的。
只要每一个进程的页表映射的是物理内存的不同区域,就可以做到进程之间不会互相干扰保证进程的独立性。

为什么要有地址空间

  1. 凡是非法的访问或者映射,os都会识别到,并终止你这个进程,有效的保护了物理内存。
    因为地址空间和页表是os创建并维护的,所以凡是使用地址空间和页表的都会在os的监控下来进行范文,这样就间接的保护了物理内存中的所有合法数据和各个进程,以及内核的相关有效数据
  2. 物理内存和进程的管理可以做到解耦合(没关联)。
    当我们申请了物理空间,但是我们不立即使用的时候,就会造成内存空间的浪费;
    针对这一现象,os做出了延迟分配的策略,来提高整机的效率。
    因为地址空间的存在,所有申请的空间都是在地址空间上申请的,物理内存不是被申请到一个字节,当我们真正访问物理地址的时候,才执行内存相关的算法。帮助申请内存,构建页表之间的映射关系,这些都是由os自主完成的
  3. 因为在物理内存中理论上随意加载,也是随意存放的,但是通过地址空间的虚拟地址和页表之间的映射,从进程视角来看所有的内存分布就成有序的了。
    因为有地址空间的存在,每一个进程都认为自己单独有一块4GB(32)空间,并且各个区域是有序的。进而通过页表映射到不同区域,来实现进程的独立性,各个进程是不知道其他进程的存在的

回答问题,为什么地址相同值不同
在这里插入图片描述

发生了写时拷贝!,所以父子进程各自其实在物理内存中,有属于自己的变量空间!只不过在用户层用同一个变量(虚拟地址!)来标识了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/71923.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

设备工单管理系统如何实现工单流程自动化?

设备工单管理系统属于工单系统的一种&#xff0c;基于其丰富的功能&#xff0c;它可以同时处理不同的多组流程&#xff0c;旨在有效处理发起人提交的事情&#xff0c;指派相应人员完成服务请求和记录全流程。该系统主要面向后勤管理、设备维护、物业管理、酒店民宿等服务行业设…

城市最短路

题目描述 下图表示的是从城市A到城市H的交通图。从图中可以看出&#xff0c;从城市A到城市H要经过若干个城市。现要找出一条经过城市最少的一条路线。 输入输出格式 输入格式&#xff1a; 无 输出格式&#xff1a; 倒序输出经过城市最少的一条路线 输入输出样例 输入样例…

运维监控学习笔记4

系统监控&#xff1a; CPU&#xff1a; 内存&#xff1a; IO INPUT/OUTPUT&#xff08;网络、磁盘&#xff09; CPU三个重要概念&#xff1a; 上下文切换&#xff1a;CPU调度器实施的进程的切换过程&#xff0c;称为上下文切换。CPU寄存器的作用。 上下文切换越频繁&#…

【图像去噪的扩散滤波】基于线性扩散滤波、边缘增强线性和非线性各向异性滤波的图像去噪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

网络安全(黑客)自学路线/笔记

想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全…

有没有推荐的golang的练手项目?

前言 下面是github上的golang项目&#xff0c;适合练手&#xff0c;可以自己选择一些项目去练习&#xff0c;整理不易&#xff0c;希望能多多点赞收藏一下&#xff01;废话少说&#xff0c;我们直接进入正题>>> 先推荐几个教程性质的项目&#xff08;用于新手学习、巩…

欧拉公式之证明

首先&#xff0c;我们考虑复数函数的泰勒级数展开式。对于任意一个复数函数f(z)&#xff0c;我们可以将其在za处进行泰勒级数展开&#xff1a; f(z) f(a) f(a)(z-a) f(a)(z-a)^2/2! f(a)(z-a)^3/3! ... 其中f(a)表示f(z)在za处的导数&#xff0c;f(a)表示f(z)在…

Ctfshow web入门 XXE 模板注入篇 web373-web378 详细题解 全

CTFshow XXE web373 学习资料&#xff1a; &#xff08;梭哈~&#xff09; https://www.cnblogs.com/20175211lyz/p/11413335.html https://www.cnblogs.com/zhaijiahui/p/9147595.html https://www.cnblogs.com/r00tuser/p/7255939.html https://mp.weixin.qq.com/s?__bizMz…

python中yield关键字

yield和return 理解一个东西最好的办法就是找一个和它类似的东西&#xff0c;然后再搞清楚它们之间的区别。 yield最类似的东西就是return&#xff0c;因为他们起到了同样的作用&#xff1a;返回值。 看这个return的函数&#xff1a; def have_some_wine():print(先开一瓶酒&a…

虚幻5中Lumen提供哪些功能以及如何工作的

虚幻引擎 5 中的 Lumen 是一个完全动态的全局照明和反射系统。它可以在虚幻引擎 5 中使用&#xff0c;因此创作者无需自行设置。它是为下一代控制台和建筑可视化等高端可视化而设计的。那么它提供了哪些功能以及如何工作&#xff1f; 全局照明 当光离开光源时&#xff0c;它会…

【TI毫米波雷达笔记】MMWave配置流程避坑

【TI毫米波雷达笔记】MMWave配置流程避坑 在TI SDK目录下的mmwave.h文档说明中 强调了要按以下配置&#xff1a; mmWave API The mmWave API allow application developers to be abstracted from the lower layer drivers and the mmWave link API.The mmWave file should b…

【设计模式】适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式&#xff0c;它结合了两个独立接口的功能。 这种模式涉及到一个单一的类&#xff0c;该类负责加入独立的或不兼容的接口功能。举个真实的例子&#xff…

Android多渠道打包+自动签名工具 [原创]

多渠道打包自动签名工具 [原创] github源码&#xff1a;github.com/G452/apk-packer 程序体验下载地址&#xff1a;github.com/G452/apk-packer.exe 如果觉得有帮助可以点个小星星支持一下&#xff0c;万分感谢&#xff01; 使用步骤&#xff1a; 1、在apk-packer.exe目录内放…

【数据结构】“栈”的模拟实现

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

FastAPI入门

目录 FastAPI FastAPI 是什么 为什么要用 FastAPI FastAPI 入门 安装 用 FastAPI 写个接口 调试接口 创建快捷请求 保存为快捷请求 发送请求 总结 FastAPI FastAPI 是什么 什么是 FastAPI 呢&#xff1f; FastAPI 是 Python 的一个框架&#xff0c;如果要类比的话…

Python-OpenCV中的图像处理-形态学转换

Python-OpenCV中的图像处理-形态学转换 形态学转换腐蚀膨胀开运算闭运算形态学梯度礼帽黑帽形态学操作之间的关系 形态学代码例程 形态学转换 形态学操作:腐蚀&#xff0c;膨胀&#xff0c;开运算&#xff0c;闭运算&#xff0c;形态学梯度&#xff0c;礼帽&#xff0c;黑帽等…

① vue复习。从安装到使用

vue官网&#xff1a;cn.vuejs.org vue安装 cnpm install -g vue/cli 查看是否安装成功 vue --version 创建一个项目 vue create vue-demo(项目名称) 这个取消掉。空格可选中或者取消。 运行项目&#xff1a; cd 进入到项目下 npm run serve 运行成功后&#xff0c;访问这…

【Linux】【驱动】驱动框架以及挂载驱动

【Linux】【驱动】驱动框架以及挂载驱动 绪论1.配置开发环境2. 编写驱动文件3. 编译Makefile文件4.编译5. 挂载驱动注意:有些开发板打开了或者禁止了printk信息&#xff0c;导致你看到的实验现象可能不一样&#xff0c;此时已经将文件移动到了开发板中&#xff0c;开发板查看文…

接口mock常用工具

在进行测试时&#xff0c;我们经常需要模拟接口数据&#xff0c;尤其是在前后端分离项目的开发中&#xff0c;在后端未完成开发时&#xff0c;前端拿不到后端的数据&#xff0c;就需要对后端返回的数据进行模拟。 如下一些工具&#xff0c;可以完成接口的mock。 Yapi 首先添…

Redis_安装、启动以及基本命令

2.Redis安装 2.1前置处理环境 VMware安装安装centOS的linux操作系统xshellxftp 2.2 配置虚拟机网络 按ctrlaltf2 切换到命令行 cd (/)目录 修改/etc/sysconfig/network-scripts/ifcfg-ens3 vi 命令 按insert表示插入 按ctrlesc退出修改状态 :wq 写入并退出 此文件必须保持一…
最新文章