我是否需要在回调中释放IntPtr?

时间:2016-07-19 17:10:35

标签: c# memory-leaks marshalling intptr

我在C / C#边界上编组数据。我有以下结构:

[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;
}

回调定义如下:

[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!
}

我的问题是,我是否需要担心在回调中释放IntPtr(ptrToMessage)以避免内存泄漏?我尝试在其上调用FreeHGlobal,但最终出现以下异常:

  

未处理的类型异常   mscorlib.dll中出现'System.Runtime.InteropServices.COMException'

     

其他信息:句柄无效。 (例外   HRESULT:0x80070006(E_HANDLE))

所以我要么做错了,要么记忆不需要我释放。

1 个答案:

答案 0 :(得分:2)

这个记忆是由你分配的?如果是这样 - 是的,很可能你必须自己释放它。如果没有......

您使用的API是什么?它是否表明你必须释放那个记忆?分配器的用途是什么?它是否定义了释放内存的方法?如果是的话 - 是的,你必须释放它。如果没有......

不,你不应该发布它。例如,它可能只是指向堆栈上分配的结构的指针。

如果你有一个指针,那并不意味着它是一个动态分配的内存。