请考虑以下代码段。
if (fork() == 0)
{
a = a + 5;
printf("%d, %d \n", a, &a);
}
else
{
a = a - 5;
printf ("%d, %d \n", a,& a);
}
AFAIK,当创建fork()时,父级的虚拟地址空间被复制到子级,并且子级& parent共享相同的物理页面,直到其中一个尝试修改。当下其中一个孩子& parent修改变量,将parent的物理页面复制到子页面的另一个页面,并且物理页面保持私有。 所以,这里'a'的值在child&中是不同的。家长。但是当涉及到儿童和儿童的'a'地址时父级,输出相同。即使物理页面不同,我也无法弄清楚为什么地址保持不变。
答案 0 :(得分:7)
a
的地址不是实际的实际地址。
这是一个虚拟地址 硬件/操作系统层将虚拟地址映射到物理地址(无形地映射到您的应用程序)。
因此,即使地址具有相同的number
,它们也不会映射到ram芯片上的相同物理内存。
PS。使用printf()打印地址(即指针)时最好使用“%p”
答案 1 :(得分:3)
响应几乎在您的问题中:修改a
后,a
的物理页面被复制(因此与父进程中的不同),但是虚拟地址(由您的程序通过&a
)不会改变。
事实上,在为a
分配新值时更改a
的虚拟地址会非常尴尬。考虑如果您之前存储了指向 int *p = &a;
a = a - 5;
printf("%d", *p)
的指针会发生什么:
a
在第二行p之后不再指向{{1}},这是一种程序员不会期望的行为。
对物理页面使用copy-on-write是对程序行为无关的操作系统的优化:您可以考虑在分叉时复制整个地址空间。