title: printf and getenv
body: <p>Ubuntu 10.04, C, gcc, x86 Intel proc:</p>
  
  <p>When trying to print the address of an environmental variable using printf, the address printed is not correct in this toy program (this is a consciously backward version in which I tried to isolate the source of the problem by saving the address value on the heap, not using a pointer directly as I read it can be overwritten, and using a pointer straight up produced the same issue):</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  int main(){
  
      const char* d = getenv("TEST");
      unsigned i = (unsigned*) malloc(sizeof(unsigned));
      i = (unsigned*) d;
  
      printf("%s at location 0x%8d.\n", "TEST", i);
  
  }
  </code></pre>
  
  <hr>
  
  <p>EDIT: same issue with this (the original) version)</p>
  
  <pre><code>int main(){
  
      const char* d = getenv("TEST");
      printf("%s at location %p.\n", "TEST", d);
  
      return 0;
  }
  </code></pre>
  
  <h2><em>This question has nothing to do with how to print a pointer. Kindly read on.</em></h2>
  
  <p>If I change the program to not print TEST's address, but TEST as a string (its value), no problem.</p>
  
  <p>However, the address returned is not the address at which the environmental variable is actually located before entering the print sub-routine; and which, by the above set-up, should be printed. Using main's disassembly and TEST's address in the eax register, I am referred to the proper location of the TEST variable, which is a little further down than main's stack frame at about 0xbffffiii on my system (i any hex value). The address value printed is on the order of 0xbfeiiiii.</p>
  
  <p>I don't understand. Is this a security precaution to prevent environmental variables from being overwritten (eg, to smash the stack)? If yes, does the compiler really keep track of transferring the address as I do above, and silently adjusting its value? </p>
  
  <p>Or am I missing something? (probably)</p>
  
  <p>Many thanks.</p>
  
  <p>P.S.: To remove imaginable sources of issues, I compiled first with no options, then:
  gcc -O0 -static -fno-stack-protector -g program.c</p>