Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C# clean up C++ allocated memory?

Tags:

c++

c#

interop

com

I have a hypothetical COM object with the following signature

void MemAlloc(ref double[] test, int membercount)

where the memory is allocated in C++ using new/malloc. Once this is in C#, using the RCW, how do I ensure that the memory is freed correctly? I would think it would be difficult for .NET to free, considering in C++ you need to know if it was allocated with new/malloc/mm_malloc before you can correctly free it. So, what is the appopriate way to cleanup my C++ allocated array? Thanks.

like image 557
Steve Avatar asked Mar 26 '09 14:03

Steve


2 Answers

I believe you should use CoTaskMemAlloc() for memory that you want to explicitly free from the managed side. The CLR will take care of freeing the memory once it's no longer reachable. If you want to free it explicitly you can use the managed Marshal.CoTaskFree() routine.

In general the interop marshaler and CLR abide by COM conventions for freeing memory; the recipient is responsible for freeing memory. So the CLR/Interop marshaler will usually take care of freeing memory that was allocated in a native call if that memory is returned to the managed caller.

From Memory Management with the Interop Marshaler (msdn):

The interop marshaler always attempts to free memory allocated by unmanaged code. This behavior complies with COM memory management rules, but differs from the rules that govern native C++.

Confusion can arise if you anticipate native C++ behavior (no memory freeing) when using platform invoke, which automatically frees memory for pointers. For example, calling the following unmanaged method from a C++ DLL does not automatically free any memory.

The runtime always uses the CoTaskMemFree method to free memory. If the memory you are working with was not allocated with the CoTaskMemAlloc method, you must use an IntPtr and free the memory manually using the appropriate method.

like image 50
Shea Avatar answered Oct 19 '22 16:10

Shea


Wrap it in an object that implements IDisposable and make sure that the C# wrapper gets disposed.

Here's a blog I wrote about an easy way to implement IDisposable.

like image 36
plinth Avatar answered Oct 19 '22 17:10

plinth