不,你不能只使用任何你想释放内存的方法。你必须使用分配器要求你使用的任何东西。只有分配给定内存块的内存管理器知道如何正确释放该内存块。
例如,Marshal.AllocHGlobal() 的文档指出:
此方法从 Kernel32.dll 公开 Win32 LocalAlloc 函数。
当 AllocHGlobal 调用 LocalAlloc 时,它会传递一个 LMEM_FIXED 标志,这会导致分配的内存被锁定到位。此外,分配的内存不是零填充的。
LocalAlloc() 的文档指出:
要释放内存,请使用 LocalFree 函数。使用 GlobalFree 释放使用 LocalAlloc 分配的内存是不安全的。
Marshal.FreeHGlobal() 使用的是什么:
FreeHGlobal 公开 Kernel32.DLL 中的 LocalFree 函数,该函数释放所有字节,因此您不能再使用 hglobal 指向的内存。
因此,允许 C# 代码使用 Marshal.AllocHGlobal() 分配内存,然后 C++ 代码使用 LocalFree() 释放该内存。相反,C++ 代码使用LocalAlloc(LMEM_FIXED) 分配内存,然后C# 代码使用Marshal.FreeHGlobal() 释放该内存。
同样,Marshal 类也有一个Marshal.AllocCoTaskMem() 方法:
此方法公开 COM CoTaskMemAlloc 函数,称为 COM 任务内存分配器。
CoTaskMemAlloc() 分配的内存被CoTaskMemFree() 释放:
释放之前通过调用 CoTaskMemAlloc 或 CoTaskMemRealloc 函数分配的任务内存块。
Marshal.FreeCoTaskMem() 使用的是什么:
FreeCoTaskMem 公开了 COM CoTaskMemFree 函数,该函数会释放所有字节,这样您就不能再使用 ptr 参数指向的内存了。
因此,允许 C# 代码使用 Marshal.AllocCoTaskMem() 分配内存,然后 C++ 代码使用 CoTaskMemFree() 释放该内存。相反,C++ 代码使用CoTaskMemAlloc() 分配内存,然后C# 代码使用Marshal.FreeCoTaskMem() 释放该内存。
现在,话虽如此,C++ 用于其new 和delete 运算符的内存管理器是实现定义的。不能保证(或可能)new 使用 LocalAlloc() 或 CoTaskMemAlloc(),或者 delete 使用 LocalFree() 或 CoTaskMemFree()。
因此,对于 C# 来说,释放由 new 分配的任何内存是不合法的,对于 C++ 来说,释放由 C# 分配的任何内存是不合法的。