如何正确释放指向非托管数组的IntPtr

本文关键字:数组 IntPtr 何正确 释放 | 更新日期: 2023-09-27 18:17:55

我分配IntPtr指向非托管代码使用的结构数组。我找到了很多关于这个主题的资源,下面是我的最终方法(似乎工作得很好):

public IntPtr ArrayToPtr<T>(T[] array)
{
    int size = array.Length;
    int elemSize = Marshal.SizeOf(typeof(T));
    IntPtr result = Marshal.AllocHGlobal(elemSize * size);
    for (int i = 0; i < size; i++)
    {
        IntPtr ptr = new IntPtr(result.ToInt64() + elemSize * i);
        Marshal.StructureToPtr(array[i], ptr, false);
    }
    return result;
}

现在我的问题:

  • 如何正确释放这导致IntPtr指针?(FreeHGlobal(指针)是足够的吗?)
  • 如果我使用x86或x64系统/应用程序平台,有什么预防措施吗?

对于字符串数组(C中的char**)也有同样的问题:

public IntPtr ArrayOfStringToPtr(string[] array)
{
    int size = array.Length;
    int elemSize = IntPtr.Size;
    IntPtr result = Marshal.AllocHGlobal(elemSize * size);
    for (int i = 0; i < size; i++)
    {
        IntPtr strPtr = Marshal.StringToHGlobalAnsi(array[i]);
        Marshal.StructureToPtr(strPtr, new IntPtr(result.ToInt64() + elemSize * i), false);
    }
    return result;
}

如何正确释放指向非托管数组的IntPtr

是的,您只需要在使用完内存后调用Marshal.FreeHGlobal(hglobal)

由于您使用的是IntPtr,它将自动在x86 x64平台上工作,因为IntPtr会为您处理指针大小的差异。

但是,您不应该使用ToInt64()来执行指针运算。

代替

IntPtr ptr = new IntPtr(result.ToInt64() + elemSize * i);

这样做:

 IntPtr ptr = IntPtr.Add(result, elemSize * i);