C# deallocate memory referenced by IntPtr

Dave picture Dave · Feb 19, 2010 · Viewed 8.7k times · Source

I am using some unmanaged code that is returning pointers (IntPtr) to large image objects. I use the references but after I am finished with the images, I need to free that memory referenced by the pointers. Currently, the only thing that frees the memory is to shutdown my entire app. I need to be able to free that memory from inside my application.

Here is the call to that allocates the memory. hbitmap is the pointer that is returned and needs to be deallocated.

[DllImport("twain_32.dll", EntryPoint = "#1")]
public static extern TwainResult DsImageTransfer(
    [In, Out] Identity origin, [In] Identity dest, DataGroup dg, 
    DataArgumentType dat, Message msg, ref IntPtr hbitmap);

Answer

casperOne picture casperOne · Feb 19, 2010

You need to use the specific memory allocator mechanism that was used to allocate the memory in the first place.

So, if you were using COM and the IMalloc interface to allocate the memory, then you have to pass the IntPtr back to the Free method on that implementation in order to free the memory allocated.

If you are indeed using the COM allocator that is returned by a call to CoGetMalloc, then you can call the static FreeCoTaskMem method on the Marshal class.

The Marshal class also has a method for freeing memory that is allocated through a call to LocalAlloc called FreeHGlobal.

However, and this is a common case, if the memory was allocated by the new operator in C++, or a call to malloc in C, then you have to expose a function in unmanaged code through interop which will free the memory appropriately.

In the case of C++, you would expose a function that takes a pointer and simply calls delete on that pointer. In the case of malloc, you would create a function that takes a pointer, and calls free on that pointer.

In specific regards to your question, it would seem that DsImageTransfer is a vendor-specific API (one that doesn't have much discoverability on the web either, I'm afraid), so more information is needed about that specific API function and how it allocates memory. Just knowing the handle type (an HBITMAP in this case) doesn't give any indication as to how it's allocated. It can be allocated with all the mechanisms mentioned above.

Assuming it is creating the HBITMAP using GDI Object api functions (specifically, the CreateBitmap function), then you could use the DeleteObject function to release the handle (as per the documentation page for the GDI Object API functions).