What happens to address's, values, and pointer

2019-04-09 06:42发布

问题:

I'm working on a question where I am to examine values and address before and after a fork() call in C. My approach was to display the variables values and address assuming to see a difference in the address after the fork(). Much to my surprise address's for said variables remained the same.

My questions is why are they the same? 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 address is the same for both parent and child.

code(for reference):

#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; 
}

output(for refrence):

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

回答1:

The child process has a copy of the parent address space. In modern systems addresses are virtualized, so that any particular pointer address in one process can map to a different physical address in another process.

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

The child has its own copy of the variable, so changing a variable in the child will not affect the value of the variable in the parent.

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

This is due to the same address in both processes mapping to different physical addresses.



回答2:

The address is the same, but doesn't refer to the same memory. Each process has its own address space. This is accomplished on modern systems by virtual memory - on older systems it would be accomplished by segment-base addressing or simply swapping (unloading one process and loading the other one in the same region of memory).