【问题标题】:Is this IntPtr pointing to allocated unmanaged memory or not?这个 IntPtr 是否指向分配的非托管内存?
【发布时间】:2013-06-06 13:53:30
【问题描述】:

首先,我分配内存并获取指针:

IntPtr pointer = Marshal.AllocHGlobal(size);

然后,我尝试释放指针指向的内存:

Marshal.FreeHGlobal(pointer);

但在我的应用程序中,它有时会引发一个致命的未知异常,仅此解释:“内存片段已损坏”。我想这是因为我试图通过释放另一个指针来释放一个指向已经释放的内存块的指针......

我的问题是:使用 IntPtr 指针,有什么方法可以检查内存块是否仍然被分配或已经被释放?

【问题讨论】:

  • 它不能被“另一个指针”释放,只能通过这个指针(的副本)。这使它成为纯粹的程序逻辑问题。
  • 亨克是对的;解决方案不是问“这个指针有效吗?”这导致了以下情况:您分配了指针。不知何故,它被释放了——顺便说一句,这就是你的错误所在——然后其他人分配内存并且他们得到相同的指针。然后你问“这个指针有效吗?”它说“是”,你释放了别人的记忆。不要试图解决你的错误; 找到您的错误并修复它
  • 也有可能你得到错误不是因为块被双重释放,而是因为你在块的有效大小之前或之后写入了内存。试试这个:当你分配块时,分配它十六个字节太大。放入八个字节,比如DEADBEEFBAADF00D——在调试器中很容易看到! -- 插入开头和结尾的额外八位,然后在使用之前将八个字节添加到指针中。您现在有一个由已知字节包围的有效缓冲区。当你去释放它时,减去八个字节并检查哨兵是否仍然存在。
  • @EricLippert “别人”是什么意思?你的意思是另一个应用程序?
  • @EricDavid:我的意思是你的应用程序中的其他代码。请记住,所谓的“全局堆”对于您的进程是全局的,而不是对于操作系统。该名称是从 Windows 3 遗留下来的,在其中可以分配由每个应用程序共享的内存——在 Win3 中,您将使用 LocalAlloc 来表示您不打算在应用程序之间共享的内存。现在他们做同样的事情。

标签: c# marshalling unmanaged unmanaged-memory


【解决方案1】:

释放指针的好方法是 Marshal.FreeHGlobal(),所以如果它被释放,这是一个逻辑问题,但你可以在 try/catch 中这样做,所以如果你进入 catch 异常,它已经被释放.

【讨论】:

  • 然后呢?现在您已经在一个堆损坏的程序中发现了一个异常。正确的做法是记录异常,然后在造成任何伤害之前关闭应用程序。
猜你喜欢
  • 1970-01-01
  • 2013-03-14
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 2014-04-22
  • 2011-07-13
相关资源
最近更新 更多