不同进程的相同内存地址

Gui*_* S. 2 c memory-management shared-memory

我只是不明白为什么这段代码会按照它的方式工作(而不是我所期望的):

 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/wait.h>
 #include <sys/types.h>

 int main()
 {
     int buffer;
     int* address;

     address=&buffer;


     if(fork()==0)
     {
         *address=27;
         printf("Address %ld stores %d\n",(long)address,*address);
         exit(0);
     }
     wait(NULL);

     printf("Address %ld stores %d\n",(long)(&buffer),buffer);    
     return 0;
 }
Run Code Online (Sandbox Code Playgroud)

为什么系统会存储不同的变量,即使它们指向相同的内存地址?

注意:我从没想过这段代码会起作用,否则整堆管道和东西都没有任何意义;我只是想了解这里发生了什么。

小智 5

这不是真正的 C 问题,而是关于(现代)操作系统的行为。

简而言之:现代操作系统上的用户空间程序在一些私有虚拟地址空间中运行。访问内存时,虚拟地址被转换为物理地址。实际内存和虚拟地址空间之间的映射是由操作系统设置的——内存被分成页面,页面可以“映射”到进程的地址空间中。

fork()通常只是将相同的内存映射到它创建的第二个进程,但是一旦写入该内存,就会复制页面并映射副本(“写时复制”)。用户空间程序永远不会看到不同用户空间程序私有的内存。

我相信您可以通过搜索此答案中给出的关键词轻松找到更多详细信息。

  • @Guillermo.DS 还查找 MMU(内存管理单元).. 地址的转换是在硬件中完成的,所以,不,至少对于没有内核权限的进程没有办法解决并非没有硬件缺陷或操作系统本身存在一些可利用的漏洞。只有内核可以设置 MMU 使用的页表。 (2认同)
  • 确实有_are_ 有时特定于操作系统的方式(例如,在 intel linux 下,您可以映射 /dev/mem)。但这是高度特定于平台和架构的。 (2认同)