繁体   English   中英

在 C++ 代码中删除在 C# 中分配的内存

[英]Delete memory allocated in C# in C++ code

我有 C#(核心)和 C++(非托管 DLL)之间的代码互操作。

在 C# 中使用Marshal.AllocHGlobal()分配的内存需要在 C# 中使用Marshal.FreeHGlobal()释放。

在 C++ 中使用new分配的内存需要在 C++ 中使用delete释放。

我可以FreeHGlobal() deleteFreeHGlobal()吗,因为 GC 不再跟踪这些内存处理程序?

不,你不能只使用任何你想释放内存的方法。 您必须使用分配器要求您使用的任何内容。 只有分配给定内存块的内存管理器知道如何正确释放该内存块。

例如, 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++ 用于其newdelete运算符的内存管理器是implementation-defined 不能保证(或可能性) new使用LocalAlloc()CoTaskMemAlloc() ,或者delete使用LocalFree()CoTaskMemFree()

因此,C# 释放任何用new分配的内存或 C++ delete C# 分配的任何内存都是不合法的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM