A .NET application calls C dll. The C code allocates memory for a char array and returns this array as result. The .NET applications gets this result as a string.
The C code:
extern "C" __declspec(dllexport) char* __cdecl Run()
{
char* result = (char*)malloc(100 * sizeof(char));
// fill the array with data
return result;
}
The C# code:
[DllImport("Unmanaged.dll")]
private static extern string Run();
...
string result = Run();
// do something useful with the result and than leave it out of scope
Some tests of it show that the garbage collector does not free the memory allocated by the C code.
Any help will be appreciated. :)
Managed string is not the same as char*. What happens undercover is that the marshaling code in the interop layer makes a copy of the unmanaged string in order to convert it to a managed string, but it can't free that memory as it does not know how it was allocated.
However, you could try allocating and returning a BSTR instead of a char*. The interop layer deals way better with automation datatypes than classic unmanaged data types.
The reason why that matters is the way char* and BSTRs are allocated in the memory.
The char* buffers are allocated on the heap of the C++ runtime using private allocation/deallocation routines that the CLR knows nothing about, so there's no way it can delete that memory. And to make things even worse, the buffer that char* points can be allocated by an internal heap implementation of the dll code, or it might even point to a member variable in a private class.
The BSTRs on the other hand are allocated using the WIndows API SysAllocString and are freed by SyFreeStirng and since the CLR interop layer knows about these Windows APIs, it knows how to free a BSTR it got from unmanaged code.