我在C#(核心)和C ++(非托管DLL)之间互操作。
使用Marshal.AllocHGlobal()
在C#中分配的内存需要使用Marshal.FreeHGlobal()
在C#中释放。
使用new
在C ++中分配的内存需要使用delete
在C ++中释放。
由于GC不再跟踪这些内存处理程序,我可以随时随地使用delete
或FreeHGlobal()
吗?
不,您不能仅使用任何想要释放内存的方法。您必须使用要使用的分配器requires。只有分配给定内存块的内存管理器才知道如何正确释放该内存块。
例如,Marshal.AllocHGlobal()
的文档说明:
此方法从Kernel32.dll公开Win32 LocalAlloc函数。>]。>
AllocHGlobal调用LocalAlloc时,它将传递一个LMEM_FIXED标志,这将导致分配的内存被锁定在适当的位置。另外,分配的内存不是零填充。
以及
Marshal.AllocHGlobal()
的文档说明:。使用GlobalFree释放用LocalAlloc分配的内存是不安全的。要释放内存,请使用LocalFree功能
LocalAlloc()
使用什么:FreeHGlobal从Kernel32.DLL公开LocalFree函数,该函数释放所有字节,以便您不再可以使用hglobal指向的内存。
因此,允许C#代码使用
LocalAlloc()
分配内存,然后允许C ++代码使用Marshal.FreeHGlobal()
释放该内存。相反,对于C ++代码,使用Marshal.FreeHGlobal()
分配内存,然后使C#代码使用Marshal.AllocHGlobal()
释放该内存。同样,
LocalFree()
类也具有LocalAlloc(LMEM_FIXED)
方法:,它被称为COM任务内存分配器。此方法公开COM CoTaskMemAlloc函数
Marshal.FreeHGlobal()
分配的内存已由Marshal
释放:释放先前通过调用CoTaskMemAlloc或CoTaskMemRealloc函数分配的任务内存块。
Marshal.AllocCoTaskMem()
使用的是什么:FreeCoTaskMem公开COM CoTaskMemFree函数
,它将释放所有字节,因此您将无法再使用ptr参数指向的内存。因此,允许C#代码使用
Marshal.AllocCoTaskMem()
分配内存,然后允许C ++代码使用CoTaskMemAlloc()
释放该内存。相反,对于C ++代码,使用CoTaskMemAlloc()
分配内存,然后使C#代码使用CoTaskMemFree()
释放该内存。现在,这么说,C ++用于其
。无法保证(或不可能)CoTaskMemFree()
和Marshal.FreeCoTaskMem()
运算符的内存管理器是实现定义的Marshal.FreeCoTaskMem()
使用Marshal.AllocCoTaskMem()
或CoTaskMemFree()
,或CoTaskMemAlloc()
使用Marshal.FreeCoTaskMem()
或new
。
因此,C#释放用delete
分配的任何内存,或C ++释放new
C#分配的任何内存都是不合法的。