【Linux】程序地址空间

这篇具有很好参考价值的文章主要介绍了【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没有受到影响,但是他们的地址都是一样的,这是为什么呢?

【Linux】程序地址空间,Linux,linux

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

什么是地址空间

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

目前我们先不考虑解析这里的共享区【Linux】程序地址空间,Linux,linux

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

  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 }


【Linux】程序地址空间,Linux,linux

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

接下来我们来认识什么是地址空间
【Linux】程序地址空间,Linux,linux

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

【Linux】程序地址空间,Linux,linux

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

为什么要有地址空间

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

回答问题,为什么地址相同值不同
【Linux】程序地址空间,Linux,linux

发生了写时拷贝!,所以父子进程各自其实在物理内存中,有属于自己的变量空间!只不过在用户层用同一个变量(虚拟地址!)来标识了文章来源地址https://www.toymoban.com/news/detail-645848.html

到了这里,关于【Linux】程序地址空间的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【Linux初阶】进程地址空间 | CUP与可执行程序的交互原理

    【Linux初阶】进程地址空间 | CUP与可执行程序的交互原理

     🌟hello,各位读者大大们你们好呀🌟 🍭🍭系列专栏:【Linux初阶】 ✒️✒️本篇内容:计算机空间初识(子进程变量修改实验),感性理解进程虚拟地址空间,进程地址空间基础(概念、区域划分与调整、程序对内存数据的修改、按需分配虚拟地址空间),解答为什么存

    2024年02月05日
    浏览(6)
  • 【Linux】地址空间&&虚拟地址

    【Linux】地址空间&&虚拟地址

    个人主页 : zxctscl 如有转载请先通知 先先来一个测试代码: 编译运行: 子进程把数据改了,父进程的数据没有改变,但是父子地址是一样的。 这个地址绝对不是物理地址,理论上修改了数据为300之后不可能在输出有100,访问一个地址怎么可能又是100也是300。这个地址在系

    2024年04月22日
    浏览(6)
  • Linux: 进程地址空间究竟是什么?进程地址空间存在意义何在?

    Linux: 进程地址空间究竟是什么?进程地址空间存在意义何在?

     在C/C++中,我们常将内存分为: 代码区、常量区、全局区(静态区)、堆、栈 等等。相关内存区域划分如下:(X86, 32位平台) 如何验证C/C++中各区域的相对位置呢?  我们可以在每个区域中选择一个地址来验证C/C++中各区域的相对位置!!具体如下: 【源代码】: 【运行

    2024年04月08日
    浏览(10)
  • Linux--进程地址空间

    Linux--进程地址空间

    1.线程地址空间 所谓进程地址空间(process address space),就是从进程的视角看到的地址空间,是进程运行时所用到的虚拟地址的集合。 简单地说,进程就是内核数据结构和代码和本身的代码和数据,进程本身不能访问物理地址,之时候就需要有一个中间媒介,就是地址空间,

    2024年02月11日
    浏览(9)
  • 【Linux】—— 进程地址空间

    【Linux】—— 进程地址空间

    序言: 在上篇中,我们讲解了关于进程优先级的概念。本期,我将给大家介绍的是关于进程地址空间的话题。 目录 (一)程序地址空间回顾 (二)代码演示 (三)进程地址空间的引入 总结 我们在学习C/C++语言的时候,大家可能都见过这样的空间布局图: 一个程序有哪些

    2024年02月15日
    浏览(10)
  • 浅析Linux进程地址空间

    浅析Linux进程地址空间

    现代处理器基本都支持虚拟内存管理,在开启虚存管理时,程序只能访问到虚拟地址,处理器的内存管理单元(MMU)会自动完成虚拟地址到物理地址的转换。基于虚拟内存机制,操作系统可以为每个运行中的进程创建独享的虚拟地址空间,在这个空间中执行的程序,无法感知

    2024年01月20日
    浏览(12)
  • 【Linux】虚拟地址空间

    【Linux】虚拟地址空间

    对于C/C++程序,我们眼中的内存是这样的: 我们利用这种对于与内存的理解看一下下面这段代码: 运行结果: 观察父子进程中 val 变量的值,以及 val 的地址,我们发现父子进程中 val 的地址都是同一个地址 但是 val 的值并不相同,这是什么意思???内存中同一个地址却存

    2023年04月08日
    浏览(6)
  • Linux:进程地址空间

    Linux:进程地址空间

    目录 1.程序地址空间  2.进程地址空间 我们在讲C/C++语言的时候,32位平台下,我们见过这样的空间布局图 我们来验证一下这张图的正确性: 运行结果: 通过观察静态变量的位置,可以认为静态变量就是全局变量,只是静态变量只初始化一次,有作用域的限制。 这里栈区还

    2024年02月04日
    浏览(15)
  • 【Linux】深挖进程地址空间

    【Linux】深挖进程地址空间

    作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等 座右铭:松树千年终是朽,槿花一日自为荣。 目标:熟悉【Linux】进程地址空间 毒鸡汤:也许有一天,你发觉日子特别的艰难,那可能是这次的收获特别的巨大。 望小伙伴们点赞👍收藏✨加关注哟💕💕      

    2024年02月03日
    浏览(8)
  • 『 Linux 』进程地址空间概念

    『 Linux 』进程地址空间概念

    在c/C++中存在一种 内存 的概念; 一般来说一个内存的空间分布包括 栈区 , 堆区 , 代码段 等等; 且内存是 自底向上 (由 0x00000000 至 0xFFFFFFFF ); 以该图为例: 该图即为常见的内存分布图; 正文代码段 正文代码段所存放的数据 一般为函数体的二进制代码 ; 已初始化数据区 已初始化

    2024年02月03日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包