title: C# Interop - Releasing memory allocated in unmanaged code
body: <p>I'm calling the following VC++ method</p>
  
  <pre><code>__declspec(dllexport) unsigned char* Get_Version_String()
  </code></pre>
  
  <p>from C# as follows:</p>
  
  <pre><code>internal static class NativeMethods
  {
      [DllImport("my.dll"),
          CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true, 
          CallingConvention = CallingConvention.Cdecl)]
      internal static extern string Get_Version_String();
  }
  </code></pre>
  
  <p>The above code is in a library which targets .NET 3.5. When I call this from a 3.5 assembly, it works fine; when calling it from a 4.5 assembly, however, it results in </p>
  
  <blockquote>
    <p>0xC0000374: A heap has been corrupted</p>
  </blockquote>
  
  <p>After reading <a href="https://stackoverflow.com/questions/18507600/c-sharp-dll-import-api-not-working-properly-in-vs2012-net-franework-4-5">this question</a>, I changed my method calls as follows:</p>
  
  <pre><code>[DllImport("my.dll",
      EntryPoint = "Get_Version_String",
      CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true, 
      CallingConvention = CallingConvention.Cdecl)]
  private static extern IntPtr Get_Version_String_PInvoke();
  
  internal static string Get_Version_String()
  {
      IntPtr ptr = Get_Version_String_PInvoke();
      string versionString = Marshal.PtrToStringAnsi(ptr);
      return versionString;
  }
  </code></pre>
  
  <p>This works as expected, but the answer from Hans Passant comes with a warning: </p>
  
  <blockquote>
    <p>The workaround you found is the correct one, the marshaller isn't going to try to release the memory for an <code>IntPtr</code>. Do note that this will only actually come to a good end if the C code returns a <code>const char*</code> that doesn't need to be released. You have a permanent memory leak if that's not the case.</p>
  </blockquote>
  
  <p>Since the C++ method does not return <code>const</code>, I'm going on the assumption that the workaround for my specific function will result in a memory leak.</p>
  
  <p>I cannot change the original method so I found <a href="https://stackoverflow.com/questions/33481888/pinvoke-allocate-memory-in-c-and-free-it-in-c-sharp">this other question</a> which discusses how to free memory from manged code. However, calling either <code>Marshal.FreeHGlobal(ptr)</code> or <code>Marshal.FreeCoTaskMem(ptr)</code> also throw <code>0xC0000374: A heap has been corrupted.</code></p>
  
  <p>Can anyone <br/>
  a) confirm that such a method will indeed suffer from a memory leak, and <br/>
  b) if so, suggest how to free the memory from the pointer in managed code?</p>
  
  <p>The C++ method body is, simplified, as follows:</p>
  
  <pre><code>unsigned char versionString[50];
  
  __declspec(dllexport) unsigned char* Get_Version_String()
  {
      strcpy((char *) versionString, "Key1:[xx],Key2:[xx],Key3:[xx],Key4:[xx]");
      // string manipulation
      return versionString;
  }
  </code></pre>
  
  <p>Thanks in advance, and sorry if this is trivial; I'm neither a C++ nor an Interop expert.</p>