title: Correct usage of ATL CComSafeArray when called from VB6 via OLE automation?
body: <p>I'm currently debugging some legacy ATL/C++ code which is called
  from Visual Basic 6 to find possible memory/resource leaks.</p>
  
  <p>The function called receives an array by reference:</p>
  
  <pre><code>STDMETHODIMP Process::Evaluate(
      IDispatch** pVBColl,
      SAFEARRAY** pResults,
      VARIANT_BOOL* pRetVal)
  </code></pre>
  
  <p>The corresponding IDL:</p>
  
  <pre><code>interface IProcess: IDispatch{
      [id(1337)] HRESULT Evaluate(
          [in,out] IDispatch** pVBColl,
          [in,out] SAFEARRAY(FLOAT)* pResults,
          [out,retval] VARIANT_BOOL* pRetVal);
      );
  </code></pre>
  
  <p>Now I've found three different solutions how to access and modify the
  results array and return values:</p>
  
  <p><strong>1st Solution:</strong>    </p>
  
  <pre><code>CComSafeArray&lt;FLOAT&gt;&amp; arrResults = reinterpret_cast&lt;CComSafeArray&lt;FLOAT&gt;&amp;&gt;(*pResults);
  arrResults[1] = 3.14;
  </code></pre>
  
  <p><strong>2nd solution:</strong></p>
  
  <pre><code>CComSafeArray&lt;FLOAT&gt; arrResults = *pResults;
  arrResults[1] = 3.14;
  *pResults = arrResults.Detach();
  </code></pre>
  
  <p><strong>3rd solution:</strong></p>
  
  <pre><code>CComSafeArray&lt;FLOAT&gt; arrResults;
  arrResults.Attach(*pResults);
  arrResults[1] = 3.14;
  *pResults = arrResults.Detach();
  </code></pre>
  
  <p><strong>Now the big question: Which one is correct?</strong><br>
  Which one doesn't leak?<br>
  Which is the correct way to Attach/Detach/AddRef/Release array passed by reference from VB to ATL/C++?    </p>
  
  <p>Attention: The arrays are declared [in,out] which cannot be changed.</p>