不同进程使用相同的内存地址

时间:2018-07-03 09:34:13

标签: 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;
 }

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

注意:我从未真正期望过此代码能正常工作,因为否则整个管道和其他东西都将毫无意义。我只想了解这里发生了什么。

2 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分:1)

来自wikipedia:fork操作为子代创建一个单独的地址空间。子进程具有父进程所有内存段的精确副本。

因此,基本上,您可以使用原始进程内存的不同COPY创建一个新进程。 您更改了重复进程的内存中的某些内容,它们是相同的,但是是副本,并且希望能在原始内存中看到它。 通常,进程不会直接共享内存。