C# Interop - Releasing memory allocated in unmanaged code
<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>