Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 630
Andrew Ricci Avatar asked Oct 08 '15 16:10

Andrew Ricci


Video Answer


2 Answers

The child process has a copy of the parent address space. In modern systems addresses are virtualized, so that any particular pointer address can map in one process to a different physical address than it does 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.

like image 114
davmac Avatar answered Nov 14 '22 21:11

davmac


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).

like image 40
Random832 Avatar answered Nov 14 '22 21:11

Random832