fork() 之后地址、值和指针会发生什么

What happens to address's, values, and pointers after a fork()

我正在研究一个问题,我要在 C 中的 fork() 调用之前和之后检查值和地址。我的方法是显示变量值和地址,假设在fork() 之后的地址。令我惊讶的是,上述变量的地址保持不变。

我的问题是为什么它们相同?如果我更改 child 中的变量会怎样?它会在 parent 和 child 中改变吗?如果不是,我如何才能更改该地址中的值,而 parent 和 child.

的地址相同

代码(供参考):

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

int main()
{
  int status;
  pid_t pid;

  int a = 123456;
  float b = 123.456;
  char c = 'Z';
  int *e;
  e=&a;

  //Retriving address's
  void *ap=&a, *bp=&b, *cp=&c, *ep=&e;

    printf("Parent Before Fork:\n");
    printf("Integer a: \tvalue = %d, \taddress = %p\n", a, ap);
    printf("Float b: \tvalue = %f, \taddress = %p\n", b, bp);
    printf("Char c: \tvalue = %c, \t\taddress = %p\n", c, cp);
    printf("Pointer e: \tvalue = %p, address = %p\n", e, ep);  

    pid = fork();

    if(pid > 0)
    {
      pid = wait(&status);
      printf("\nParent After Fork:\n");
      printf("Integer a: \tvalue = %d, \taddress = %p\n", a, ap);
      printf("Float b: \tvalue = %f, \taddress = %p\n", b, bp);
      printf("Char c: \tvalue = %c, \t\taddress = %p\n", c, cp);
      printf("Pointer e: \tvalue = %p, address = %p\n", e, ep);

      sleep(1);
    }
    else if(pid == 0)
    {
      printf("\nChild After Fork:\n");
      printf("Integer a: \tvalue = %d, \taddress = %p\n", a, ap);
      printf("Float b: \tvalue = %f, \taddress = %p\n", b, bp);
      printf("Char c: \tvalue = %c, \t\taddress = %p\n", c, cp);
      printf("Pointer e: \tvalue = %p, address = %p\n", e, ep);
   }
   else
     printf("fork() did not work");

return 0; 
}

输出(供参考):

Parent Before Fork:
Integer a:  value = 123456,         address = 0x7fff8b8e378c
Float b:    value = 123.456001,     address = 0x7fff8b8e3790
Char c:     value = Z,              address = 0x7fff8b8e3787
Pointer e:  value = 0x7fff8b8e378c, address = 0x7fff8b8e3798

Child After Fork:
Integer a:  value = 123456,         address = 0x7fff8b8e378c
Float b:    value = 123.456001,     address = 0x7fff8b8e3790
Char c:     value = Z,              address = 0x7fff8b8e3787
Pointer e:  value = 0x7fff8b8e378c, address = 0x7fff8b8e3798

Parent After Fork:
Integer a:  value = 123456,         address = 0x7fff8b8e378c
Float b:    value = 123.456001,     address = 0x7fff8b8e3790
Char c:     value = Z,              address = 0x7fff8b8e3787
Pointer e:  value = 0x7fff8b8e378c, address = 0x7fff8b8e3798

地址相同,但指向的不是同一内存。每个进程都有自己的地址space。这是通过虚拟内存在现代系统上实现的——在旧系统上,它将通过基于段的寻址或简单的交换(卸载一个进程并将另一个进程加载到同一内存区域)来实现。

子进程有父地址的副本space。在现代系统中,地址是虚拟化的,因此任何特定的指针地址都可以在一个进程中映射到与在另一个进程中不同的 物理地址

What happens if I change a variable in the child? Will it change in both parent and child?

子项有自己的变量副本,因此更改子项中的变量不会影响父项中变量的值。

If not, how am I able to change the value in that address while the addres is the same for both parent and child.

这是因为两个进程中的相同地址映射到不同的物理地址。