5

考虑以下代码片段。

if (fork() == 0)
{
     a = a + 5;
     printf("%d, %d \n", a, &a);
}
else
{
     a = a - 5;
     printf ("%d, %d \n", a,& a);
}

AFAIK,当创建 fork() 时,父级的虚拟地址空间被复制到子级,并且子级和父级共享相同的物理页面,直到其中一个尝试修改。当孩子和父母中的一个修改变量时,父母的物理页面被复制到另一个孩子的页面并且物理页面保持私有。所以,这里的“a”值在孩子和父母中是不同的。但是当涉及到孩子和父母中“a”的地址时,输出是相同的。即使物理页面不同,我也无法弄清楚为什么地址保持不变。

4

2 回答 2

7

的地址a不是实际的物理地址。

它是一个虚拟地址。
硬件/操作系统层将虚拟地址映射到物理地址(对您的应用程序不可见)。

因此,即使地址相同number,它们也不会映射到 ram 芯片上的相同物理内存。

PS。使用 printf() 打印地址(即指针)时最好使用“%p”

于 2012-05-23T08:33:13.930 回答
3

响应几乎在您的问题中: 的物理页面a在修改后被复制(因此与父进程中的不同)a,但虚拟地址(您的程序通过 看到的&a)没有改变。

实际上,a在分配新值时更改虚拟地址会非常尴尬。考虑一下如果您之前存储了一个指向 的指针会发生什么a

 int *p = &a;
 a = a - 5;
 printf("%d", *p)

在第二行之后 p 将不再指向a,这是任何程序员都不会想到的行为。

对物理页面使用写时复制是对操作系统的一种优化,与您的程序行为无关:您可以考虑在 fork 时复制整个地址空间。

于 2012-05-23T08:47:05.820 回答