首页 > 解决方案 > 将 IntPtr 作为函数的参数传递会导致内存泄漏吗?

问题描述

假设我有 IntPtr 变量,它的值是通过调用 WinApi 函数 (p/invoke) 分配的。然后我在 10 个不同的函数中传递了这个值。由于 IntPtr 是 struct(值类型),因此每个函数都会获得原始变量的副本。会不会导致内存泄漏?我应该关闭每个函数中原始变量的每个副本吗?

[DllImport("WinApiFunction")]
public static extern bool WinApiFunction(int arg1, int arg2, out IntPrt result)

public void Foo()
{
    var result = IntPtr.Zero;
    WinApiFunction(1, 2, out result);
    Foo1(result);
    Foo2(result);
    Foo3(result);

//...

    Foo10(result);
// ...

    CloseHandle(result);
}

标签: c#.netf#

解决方案


IntPtr通常用作句柄或指针值的占位符。很难从代码中准确判断发生了什么,但复制句柄或指针值不会复制底层资源。

所以在你的例子中,一次似乎是正确的CloseHandle。我会把它放在一个try..finally虽然,以确保如果返回一个有效的句柄,CloseHandle它总是被调用。WinApiFunction

[DllImport("WinApiFunction")]
public static extern bool WinApiFunction(int arg1, int arg2, out IntPrt result)

public void Foo()
{
  var result = IntPtr.Zero;
  if (!WinApiFunction(1, 2, out result) || result == IntPtr.Zero)
  {
    throw new Exception("Oops");
  }
  try
  {
    Foo1(result);
    Foo2(result);
  }
  finally
  {
    CloseHandle(result);
  }
}

如果您要围绕句柄构建一个代理类,则用例在代理类上实现终结器(和 IDisposable)。


推荐阅读