释放 intPtr 的动态方式
dynamic way to free intPtr
我有很大的 class ,在很多地方我需要将数组转换为 intPtr
IntPtr convertToIntPtr(Array input)
{
if (input != null)
{
int s = Marshal.SizeOf(input.GetValue(0).GetType()) * input.Length;
System.IntPtr p = Marshal.AllocHGlobal(s);
return p;
}
return new IntPtr();
}
我知道每个指针都可以使用 Marshal.FreeHGlobal(IntPtr)
释放。
我的问题是:
- 垃圾收集器会在使用后释放 intptr
- 如果没有,我怎么能在关闭或处理 class 时释放所有这些,任何要使用的事件,这样当 intpntr no far 被删除时
不,垃圾收集器不会自动释放 IntPtr。由您自己管理。我建议尽可能避免这样做,但是当您需要这样做时,您应该实施 dispose pattern.
不,您分配的内存是非 GC 处理的内存,因此不会被释放(从技术上讲,它会在您的程序结束时被释放……但我认为这不是您想要的)。
你可以做的是将 IntPtr
封装在一次性物品中。
public sealed class ArrayToIntPtr : IDisposable
{
public IntPtr Ptr { get; protected set; }
public ArrayToIntPtr(Array input)
{
if (input != null)
{
int s = Marshal.SizeOf(input.GetValue(0).GetType()) * input.Length;
Ptr = Marshal.AllocHGlobal(s);
}
else
{
Ptr = IntPtr.Zero;
}
}
~ArrayToIntPtr()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected void Dispose(bool disposing)
{
if (Ptr != IntPtr.Zero)
{
Marshal.FreeHGlobal(Ptr);
Ptr = IntPtr.Zero;
}
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
(注意 class 是 sealed
,所以 Dispose(bool disposing)
不是 virtual
)
我有很大的 class ,在很多地方我需要将数组转换为 intPtr
IntPtr convertToIntPtr(Array input)
{
if (input != null)
{
int s = Marshal.SizeOf(input.GetValue(0).GetType()) * input.Length;
System.IntPtr p = Marshal.AllocHGlobal(s);
return p;
}
return new IntPtr();
}
我知道每个指针都可以使用 Marshal.FreeHGlobal(IntPtr)
释放。
我的问题是: - 垃圾收集器会在使用后释放 intptr - 如果没有,我怎么能在关闭或处理 class 时释放所有这些,任何要使用的事件,这样当 intpntr no far 被删除时
不,垃圾收集器不会自动释放 IntPtr。由您自己管理。我建议尽可能避免这样做,但是当您需要这样做时,您应该实施 dispose pattern.
不,您分配的内存是非 GC 处理的内存,因此不会被释放(从技术上讲,它会在您的程序结束时被释放……但我认为这不是您想要的)。
你可以做的是将 IntPtr
封装在一次性物品中。
public sealed class ArrayToIntPtr : IDisposable
{
public IntPtr Ptr { get; protected set; }
public ArrayToIntPtr(Array input)
{
if (input != null)
{
int s = Marshal.SizeOf(input.GetValue(0).GetType()) * input.Length;
Ptr = Marshal.AllocHGlobal(s);
}
else
{
Ptr = IntPtr.Zero;
}
}
~ArrayToIntPtr()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected void Dispose(bool disposing)
{
if (Ptr != IntPtr.Zero)
{
Marshal.FreeHGlobal(Ptr);
Ptr = IntPtr.Zero;
}
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
(注意 class 是 sealed
,所以 Dispose(bool disposing)
不是 virtual
)