title: pointer parameter corrupted: returning the pointer or passing address of pointer works
body: <p>I'm passing a pointer to a user-defined type to a function that <code>malloc</code>'s memory and sets this pointer to point to it. <code>malloc()</code> comes back with a pointer, but when I return from the function, my pointer is clobbered.  I came up with a couple of fixes:</p>
  
  <ul>
  <li>return the pointer instead of passing it</li>
  <li>pass the address of the pointer rather than the pointer itself</li>
  </ul>
  
  <p>I suspect this is akin to the case with <code>FILE</code> pointers; if you pass the pointer to a function, you can't count on the pointer not being changed because the system may fiddle with it. So you pass the address of the <code>FILE *</code> instead.</p>
  
  <p>Anyone have an explanation for this?  Here's the code (sorry, it's a bit long):</p>
  
  <pre><code>typedef struct  {
      BOOK *bookAry;
      int numBooks;
  }INVENTORY;
  </code></pre>
  
  <p>I had this in <code>main()</code>, where <code>INVENTORY</code> is a user-defined type as above:</p>
  
  <pre><code>//variable declarations
  INVENTORY *inv = NULL;
  
  //process
  initInventory( inv, bookArySize );
  processFile( inv );
  </code></pre>
  
  <p>The <code>initInventory()</code> function is as follows:</p>
  
  <pre><code>void initInventory( INVENTORY *inv, int size ) {
  
      //process
      inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
         //more code here....
      return;
  
  }//initInventory
  </code></pre>
  
  <p>So we return to <code>main()</code> (we think) with <code>inv</code> pointing to the newly-allocated memory (and <code>inv</code> points to a struct that has other pointers).  Only when I pass the pointer <code>inv</code> to <code>processFile()</code>, it's been clobbered, and when I try to reference the data in the <code>inventory</code> struct, I get an access violation. It turns out the pointer's invalid on return to <code>main()</code>!</p>
  
  <p>This fixed it: <code>main()</code> has:</p>
  
  <pre><code>//variable declarations
  INVENTORY *inv = NULL;
  
  //process
  inv = initInventory( inv, bookArySize );
  processFile( inv );
  </code></pre>
  
  <p>and <code>initInventory()</code> is changed to this:</p>
  
  <pre><code>INVENTORY * initInventory( INVENTORY *inv, int size ) {
  
      //process
      inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
  
  
      //return a pointer to the INVENTORY header struct
      return inv;
  
  }//initInventory
  </code></pre>
  
  <p>Then I tried this, which I think is a better fix. <code>main()</code> now has:</p>
  
  <pre><code>//variable declarations
  INVENTORY *inv = NULL;
      //more code here...
  
  //process
  initInventory( &amp;inv, bookArySize );
  processFile( inv );
  </code></pre>
  
  <p>And <code>initInventory()</code> is as follows:</p>
  
  <pre><code>void initInventory( INVENTORY **inv, int size ) {
  
      //process
      *inv = ( INVENTORY * ) malloc( sizeof( INVENTORY ) );
          //more code here....
      return;
  
  }//initInventory
  </code></pre>