Do I need to release an IntPtr inside a callback?

3

I'm Marshalling data across C/C# boundary. I have the following structure:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct Message
{
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
   public string From;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
   public string Subject;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
   public string Body;
}

The callback is defined as follows:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void MessageReceiveDelegate([In]IntPtr ptrToMessage);

private void MessageReceiveCallback(IntPtr ptrToMessage)
{
    Message message = (Message)Marshal.PtrToStructure(ptrToMessage, typeof(Message));

    Marshal.FreeHGlobal(ptrToMessage); //This throws COMException!
}

My question is, do I need to worry about releasing IntPtr (ptrToMessage) inside the callback to avoid memory leaks? I tried calling FreeHGlobal on it, but end up with the following exception:

An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll

Additional information: The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))

So I'm either doing something wrong, or the memory doesn't need to be released by me.

c#
memory-leaks
marshalling
intptr
asked on Stack Overflow Jul 19, 2016 by Eternal21

1 Answer

3

This memory was allocated by you? If so - yes, most likely you will have to release it by yourself. If no...

What the API do you use? Does it states that you have to release that memory? What the allocator was used? Does it define a way to release that memory? If so - yes, you have to release it. If no...

No, you should not release it. For example, it could be just a pointer to structure allocated on stack.

If you have a pointer it does not mean it is a dynamically allocated memory.

answered on Stack Overflow Jul 19, 2016 by lorond

User contributions licensed under CC BY-SA 3.0