【发布时间】: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