我只是想不出为什么这段代码会如此工作(而不是我所期望的):
#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;
}
为什么即使它们指向相同的内存地址,系统也会存储不同的变量?
注意:我从未真正期望过此代码能正常工作,因为否则整个管道和其他东西都将毫无意义。我只想了解这里发生了什么。
答案 0 :(得分:4)
这实际上不是C问题,而是关于(现代)操作系统的行为。
简而言之:现代OS上的用户空间程序在某些私有虚拟地址空间中运行。访问内存时,虚拟地址将转换为物理地址。实际内存和虚拟地址空间之间的映射是由操作系统设置的-内存被分成页面,并且页面可以“映射”到进程的地址空间。
fork()
通常只是将相同的内存映射到它创建的第二个进程,但是一旦写入该内存,就会复制页面并映射副本(“写入时复制”)。用户空间程序将永远不会看到其他用户空间程序专用的内存。
我相信您可以轻松找到更多详细信息,以搜索此答案中给出的关键词。
答案 1 :(得分:1)
来自wikipedia:fork操作为子代创建一个单独的地址空间。子进程具有父进程所有内存段的精确副本。
因此,基本上,您可以使用原始进程内存的不同COPY创建一个新进程。 您更改了重复进程的内存中的某些内容,它们是相同的,但是是副本,并且希望能在原始内存中看到它。 通常,进程不会直接共享内存。