Linux的学习之路:11、地址空间

简介: Linux的学习之路:11、地址空间

一、空间布局图

如下方图片可以看出地址空间有几种,这里没有画全,这里就是说一下正文代码空间也就是代码段、初始化数据、未初始化数据、堆、栈、命令行参数环境变量。

这里利用代码进行测试一下,看看是否和上面说的一样,如下方代码,这里测试李哥数据,如下方截图,在截图中可以看的出代码段的空间是最小的,如上方图中所示,代码空间是从下向上的,也就是下面最小上面最大,这里看可以从下方测试截图可以看出。

在下方测试截图中的可以看出栈的空间是向下增加的,堆的空间是向上增加的。

 1 #include <stdio.h>                                                                                                                                                                                            
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 
  5 int main()
  6 {
  7     printf("正文代码:%p\n",&main);
  8     int a=0;
  9     int b;
 10     printf("初始化数据空间:%p\n",&a);
 11     printf("未初始化数据空间:%p\n",&b);
 12     int* p1=(int*)malloc(10);
 13     int* p2=(int*)malloc(10);
 14     int* p3=(int*)malloc(10);
 15     int* p4=(int*)malloc(10);
 16     printf("申请的堆空间:%p\n",p1);
 17     printf("申请的堆空间:%p\n",p2);
 18     printf("申请的堆空间:%p\n",p3);
 19     printf("申请的堆空间:%p\n",p4);
 20     printf("申请的栈空间:%p\n",&p1);
 21     printf("申请的栈空间:%p\n",&p2);
 22     printf("申请的栈空间:%p\n",&p3);
 23     printf("申请的栈空间:%p\n",&p4);
 24     return 0;
 25 }


二、代码测试一下

如下图的测试就可以看出我定义了一个变量val去进行测试地址,结果在子进程中更改了数值,结果发现父进程的数值没有更改,但是两个地址是一样的,这是什么情况?得出了下方的结论:

变量内容不一样,所以父子进程输出的变量绝对不是同一个变量,但地址值是一样的,说明,该地址绝对不是物理地址!在Linux地址下,这种地址叫做 虚拟地址,我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理,OS必须负责将 虚拟地址 转化成 物理地址 。

  4 int val=100;
  5 int main()
  6 {
  7     pid_t id=fork();
  8     printf("正文代码:%p\n",&main);
  9     int a=0;
 10     int b;
 11     printf("初始化数据空间:%p\n",&a);
 12     printf("未初始化数据空间:%p\n",&b);
 13     int* p1=(int*)malloc(10);   
 14     int* p2=(int*)malloc(10);
 15     int* p3=(int*)malloc(10);
 16     int* p4=(int*)malloc(10);                                                                                                                                                                                 
 17     printf("申请的堆空间:%p\n",p1);
 18     printf("申请的堆空间:%p\n",p2);
 19     printf("申请的堆空间:%p\n",p3);
 20     printf("申请的堆空间:%p\n",p4);
 21     printf("申请的栈空间:%p\n",&p1);
 22     printf("申请的栈空间:%p\n",&p2);
 23     printf("申请的栈空间:%p\n",&p3);
 24     printf("申请的栈空间:%p\n",&p4);
 25     if(id==0)
 26     {
 27         int i=0;
 28         while(1)
 29         {
 30             if(i==5)
 31             {
 32                 val=200;
 33             }
 34             printf("子进程:%d,地址:%p\n",val,&val);
 35             sleep(1);  
 36             i++;                        
 37         }              
 38     }
 39     else                                                           
 40     {                                                            
 41         while(1)                                          
 42         {                             
 43             printf("父进程:%d,地址:%p\n",val,&val);   
 44             sleep(1);                         
 45         }                                                                                                         
 46     }                 
 47     return 0;
 48}

三、进程地址空间

之前说‘程序的地址空间’是不准确的,准确的应该说成 进程地址空间 ,那该如何理解呢?看下方图片,这里就出现了一个名词叫做页表,这个页表也就是用来储存虚拟地址的,然后通过OS处理通过这个页表进行映射从而找到物理空间,这里就可以的出上面我所用代码得出的地址只是个虚拟地址,而更改了数据后,OS就把页表中储存的虚拟地址映射的物理地址换了一个地方,所以子进程和父进程的虚拟地址使用一个。

四、测试代码

#include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 int val=100;
  5 int main()
  6 {
  7     pid_t id=fork();
  8     printf("正文代码:%p\n",&main);
  9     int a=0;
 10     int b;
 11     printf("初始化数据空间:%p\n",&a);
 12     printf("未初始化数据空间:%p\n",&b);
 13     int* p1=(int*)malloc(10);   
 14     int* p2=(int*)malloc(10);
 15     int* p3=(int*)malloc(10);
 16     int* p4=(int*)malloc(10);                                                                                                                                                                                 
 17     printf("申请的堆空间:%p\n",p1);
 18     printf("申请的堆空间:%p\n",p2);
 19     printf("申请的堆空间:%p\n",p3);
 20     printf("申请的堆空间:%p\n",p4);
 21     printf("申请的栈空间:%p\n",&p1);
 22     printf("申请的栈空间:%p\n",&p2);
 23     printf("申请的栈空间:%p\n",&p3);
 24     printf("申请的栈空间:%p\n",&p4);
 25     if(id==0)
 26     {
 27         int i=0;
 28         while(1)
 29         {
 30             if(i==5)
 31             {
 32                 val=200;
 33             }
 34             printf("子进程:%d,地址:%p\n",val,&val);
 35             sleep(1);  
 36             i++;                        
 37         }              
 38     }
 39     else                                                           
 40     {                                                            
 41         while(1)                                          
 42         {                             
 43             printf("父进程:%d,地址:%p\n",val,&val);   
 44             sleep(1);                         
 45         }                                                                                                         
 46     }                 
 47     return 0;
 48}


目录
打赏
0
0
0
0
2
分享
相关文章
|
30天前
|
零基础保姆级教程!手把手教你免费玩转Linux CentOS安装+学习环境搭建(附避坑指南)
本文详细介绍了在VMware虚拟机中安装CentOS 6.8的全过程。首先,需确保已安装VMware并开启V-CPU虚拟化功能,可通过BIOS设置或使用LeoMoon CPU-V工具检测。接着,下载CentOS镜像文件,并在VMware中新建虚拟机,配置CPU、内存、硬盘等参数。最后,加载ISO镜像启动虚拟机,按照提示完成CentOS的安装,包括语言、键盘、存储方式、地区、密码设置及硬盘分区等步骤。安装完成后,以root用户登录即可进入系统桌面,开始学习Linux命令和操作。
114 12
零基础保姆级教程!手把手教你免费玩转Linux CentOS安装+学习环境搭建(附避坑指南)
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
263 2
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
245 0
|
9天前
|
linux常用命令详细说明以及案例
本文介绍了Linux中几个常用的命令及其用法,包括:`ls`(列出目录内容)、`cd`(切换目录)、`mkdir`(创建目录)、`rm -p`(删除目录及内容)和`mv`(移动或重命名文件/目录)。每个命令都配有详细说明、语法格式、常见选项及实用案例,帮助用户更好地理解和使用这些基础命令。内容源自[linux常用命令详细说明以及案例](https://linux.ciilii.com/show/news-285.html)。
|
9天前
|
linux命令详细说明以及案例
本文介绍了常用的 Linux 命令及其详细说明和示例,包括:`ls`(列出目录内容)、`cd`(更改目录)、`rm` 和 `mv`(删除与移动文件)、`grep`(搜索文本)、`cat`(显示文件内容)以及 `chmod`(更改文件权限)。每个命令均配有功能描述、选项说明及实际案例,帮助用户更好地掌握 Linux 命令的使用方法。
94 56
|
12天前
|
Linux基础:文件和目录类命令分析。
总的来说,这些基础命令,像是Linux中藏匿的小矮人,每一次我们使用他们,他们就把我们的指令准确的传递给Linux,让我们的指令变为现实。所以,现在就开始你的Linux之旅,挥动你的命令之剑,探索这个充满神秘而又奇妙的世界吧!
59 19
|
26天前
|
Linux 常用文件查看命令
`cat` 命令用于连接文件并打印到标准输出,适用于快速查看和合并文本文件内容。常用示例包括:`cat file1.txt` 查看单个文件,`cat file1.txt file2.txt` 合并多个文件,`cat &gt; filename` 创建新文件,`cat &gt;&gt; filename` 追加内容。`more` 和 `less` 命令用于分页查看文件,`tail` 命令则用于查看文件末尾内容,支持实时追踪日志更新,如 `tail -f file.log`。
50 5
Linux 常用文件查看命令
|
1月前
|
Linux od命令
本文详细介绍了Linux中的 `od`命令,包括其基本语法、常用选项和示例。通过这些内容,你可以灵活地使用 `od`命令查看文件内容,提高分析和调试效率。确保理解每一个选项和示例的实现细节,应用到实际工作中时能有效地处理各种文件查看需求。
60 19
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等