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