The goal
Understanding what happens in the code and what have I misconcluded / mispredicted.
Context
While experimenting with fork function (and reading articles I probably misunderstood) I concluded that data used by child was a copy of parent's data.
- In order to make a child work on the same data as its parent, I created pointer p, assuming that its value will be the same in all (both) processes after forking.
- I made sure that both child's and parent's pointer was pointing to the same memory space by printing values stored by them. What stroke me to the ground, is that they also seem to be the same/exact – have the same addresses.
Shall the 2 exact pointers point to different values? In my code they did. - Next, to be sure that a compiler would not perform any optimization, I marked the p pointer as
volatile.
That did not change anything. Here is the code.
The general code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
volatile int *volatile p= malloc(sizeof(int));
*p= 6;
if (fork()){ //Parent
*p= 200; //Parent changes the value in "shared" memory
printf("Parent: %p : %p : %i\n", &p, p, *p);
wait(NULL);
}else{ //Child
sleep(3); //Child sleeps when parent is setting the "shared" value.
printf("Child: %p : %p : %i\n", &p, p, *p); //Child should read the same value.
}
}
Output:
Parent: 0x7ffc8bb6cbe0 : 0xea9260 : 200
Child: 0x7ffc8bb6cbe0 : 0xea9260 : 6
Expected outputs:
Parent: 0x7ffc8bb6cbe0 : 0xea9260 : 200
Child: 0x7ffc8bb6cbe0 : 0xea9260 : 200
Or
Parent: 0x7ffc8bb6cbe0 : 0xea9260 : 200
Child: differentAddress: 0xea9260 : 200
2nd code variation (snippet)
Still believing in the fault of compiler optimization, I added steps (sleep, fetch, sleep, copy).
if (fork()){ //Parent
*p= 200;
printf("Parent: %p : %p : %i\n", &p, p, *p);
wait(NULL);
}else{ //Child
sleep(2);
uintptr_t fetch= (uintptr_t)p;
sleep(2);
p= (int*)fetch;
printf("Child: %p : %p : %i\n", &p, p, *p);
}
This also changed nothing in the actual output.
Environment
- Language C (propably C11)
- Compiler: clang 7.0.0 (I haven't pass any of O1,O2,O3,... flags.)
- IDE & platform: https://replit.com/
- Platform: Linux-5.11.0-1029-gcp-x86_64-with-glibc2.27
- Machine: x86_64
My other attempts at understanding this
I tried also other similar experiments. That provided me with ambiguous conclusions.