【Linux系统编程】程序地址空间

简介: 【Linux系统编程】程序地址空间

进程地址空间


       进程地址空间是指每个进程在计算机内存中所占用的地址空间。地址空间是指能被访问的内存地址范围,它由若干个连续的内存块组成。每个进程都有自己的地址空间,这意味着每个进程都有自己的内存地址范围,不会与其他进程冲突。进程地址空间通常被划分为几个部分,包括代码段、数据段、堆和栈等,它是一种特定的数据结构,进程task_struct内部指向其结构,次结构在系统中叫做mm_struct。具体的结构分布如下图:


5c289a503cf84c07bf17bba10214e7c4.png


下面是在Linux下运用代码演示其地址:


[zhujunhao@bogon code]$ cat test.cpp
#include <iostream>
#include <unistd.h>
#include <cstdio>
using namespace std;
int main()
{
    char* s = new char[5];
    cout << "&s: " << &s << endl;
    int n = 8;
    cout << "&n: " << &n << endl;
    return 0;
}
[zhujunhao@bogon code]$ ./test.exe
//可看出堆区地址高,对应上面进程地址空间
&s: 0x7fff23280dc8
&n: 0x7fff23280dc4


       在vs下的测试可能还不一样,数据可能会出现异常,在Linux下可以测试出。这时因为Windows下出于安全的考虑,可能会对齐做出调整,Linux下也会做出安全考虑,只不过比Windows较为“ 优雅 ”。


物理地址与虚拟地址


       物理地址是系统内存中真正意义上存储数据所对应的一种地址,虚拟地址是模拟来的一种地址,通常与物理地址建立联系,然后从物理地址中对数据做出改变。我们平常使用C/C++中的地址都是虚拟地址。我们先来观察以下代码。


[zhujunhao@bogon code]$ cat code.cpp
#include <iostream>
#include <cstdio>
#include <unistd.h>
using namespace std;
int a = 100;
int main()
{
    pid_t p = fork();
    if (p == 0) {
        cout << "Child:" << endl;
        a = 200;
        cout << "   a = " << a << "  " << "&a = " << &a << endl; 
    }
    else {
        cout << "Father:" << endl;
        cout << "   a = " << a << "  " << "&a = " << &a << endl;
    }
    return 0;
}
[zhujunhao@bogon code]$ g++ -o code.exe code.cpp
[zhujunhao@bogon code]$ ./code.exe
//发现地址一样,但数据不一样
Father:
   a = 100  &a = 0x601074
Child:
   a = 200  &a = 0x601074

       注意,由于数据明显不一样,所以以上的地址不是物理地址,是虚拟地址/线性地址。也就是说,我们所用到的所有地址,全都不是物理地址,是虚拟或线性地址,而物理地址,用户一概看不到,由OS统一管理,其中,OS必须负责将虚拟地址转化成物理地址。


       在以上代码中,当子进程修改变量时,系统将会找到从子进程所对应的进程地址空间中的虚拟地址对应的物理地址,在物理地址内部开辟一块自己存储数据的空间,修改数据时将会修改从虚拟地址到物理地址的眏射表,眏射表将会修改那块存储数据的空间中的数据并重新建立两地址转换间的眏射关系,原本的数据不会被影响,所以,父子进程虽然虚拟地址一样,但数据不一样。


       系统之所以这样设计原因有以下三点:


       1,将物理内存从无序变有序。如果让让进程直接访问内存的话,那么每个进程存在内存中的位置都是不一样的,将会增加操作系统管理的成本。


       2,将内存管理和进程管理进行耦合。虚拟地址负责管理进程,物理地址负责管理内存。


       3,虚拟地址的设计间接保护了内存安全。如若直接访问物理地址,当用户胡乱操作时,将会造成不可逆转的损坏,虚拟地址的使用对其做出了拦截,保证了系统安全。


相关文章
|
2天前
|
JSON JavaScript Linux
Linux系统之安装cook菜谱工具
【10月更文挑战第15天】Linux系统之安装cook菜谱工具
12 2
Linux系统之安装cook菜谱工具
|
3天前
|
安全 Linux
Linux系统之lsof命令的基本使用
【10月更文挑战第14天】Linux系统之lsof命令的基本使用
25 2
Linux系统之lsof命令的基本使用
|
1天前
|
运维 网络协议 Linux
linux系统命令 losf详解
**lsof命令**(List Open Files)是Linux系统中一个非常实用的工具,用于列出当前系统上所有打开的文件以及与之关联的进程。以下是对lsof命令的详细介绍: ### 一、基本功能 lsof命令可以显示系统中被进程打开的文件,这些文件可以是普通文件、目录、网络套接字、设备文件等。通过lsof命令,用户可以方便地查看哪些文件被哪些进程打开,以及这些文件的状态信息。 ### 二、基本语法 lsof命令的基本语法为:`lsof [选项] [文件]`。其中,选项用于指定lsof命令的行为,文件则是可选的,用于指定要查询的文件。 ### 三、常用选项 * `-a` 或 `-
|
2天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。
|
1天前
|
安全 Unix Linux
Linux系统之使用cmatrix实现数字雨效果
【10月更文挑战第16天】Linux系统之使用cmatrix实现数字雨效果
8 0
Linux系统之使用cmatrix实现数字雨效果
|
3天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。
|
1天前
|
Linux Shell
Linux系统
是对Linux系统进行管理的命令。对于Linux系统来说,无论是中央处理器、内存、磁盘驱动器、键盘、鼠标,还是用户等都是文件,Linux系统管理的命令是它正常运行的核心,与之前的DOS命令类似。linux命令在系统中有两种类型:内置Shell命令和Linux命令。
|
5月前
|
缓存 Linux 测试技术
安装【银河麒麟V10】linux系统--并挂载镜像
安装【银河麒麟V10】linux系统--并挂载镜像
1419 0
|
5月前
|
关系型数据库 MySQL Linux
卸载、下载、安装mysql(Linux系统centos7)
卸载、下载、安装mysql(Linux系统centos7)
222 0
|
6天前
|
Linux
手把手教会你安装Linux系统
手把手教会你安装Linux系统