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

时间:2013-06-12 08:04:11

标签: c# marshalling intptr unmanaged-memory

我指定IntPtr指向要与非托管代码一起使用的struct数组。我在这个主题上找到了很多资源,这是我最后的方法(似乎运作良好):

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

1 个答案:

答案 0 :(得分:1)

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

因为您使用的是IntPtr,所以它会自动在x86 x64平台上运行,因为IntPtr会为您处理指针大小的差异。

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

而不是

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

这样做:

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