c# – Marshal.AllocHGlobal(0) – 为什么不返回IntPtr.Zero
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – Marshal.AllocHGlobal(0) – 为什么不返回IntPtr.Zero,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2130字,纯文字阅读大概需要4分钟。
内容图文
![c# – Marshal.AllocHGlobal(0) – 为什么不返回IntPtr.Zero](/upload/InfoBanner/zyjiaocheng/812/38f32901f90e48068ab1444bbb764a03.jpg)
试着理解这是否有意义,以及它的意义在哪里.
Marshal.AllocHGlobal(int cb)在非托管内存中分配指定的字节数.
但是为什么Marshal.AllocHGlobal(0)实际上会返回一个不是IntPtr.Zero的IntPtr?我是否应该在使用0字节时释放分配的0字节?
我看不出这个实现背后的逻辑,能有人解释一下吗?
解决方法:
1.如果分配了0个字节,为什么Marshal.AllocHGlobal不会返回IntPtr.Zero?
Marshal.AllocHGlobal在内部从WinBase.h调用WinAPI函数LocalAlloc.
至于为什么Marshal.AllocHGlobal(0)不返回IntPtr.Zero:
在分配期间发生故障时,LocalAlloc仅返回NULL(C#等效:IntPtr.Zero).
这也可以在source code中看到:
IntPtr pNewMem = Win32Native.LocalAlloc_NoSafeHandle(LMEM_FIXED, unchecked(numBytes));
if (pNewMem == IntPtr.Zero) {
throw new OutOfMemoryException();
}
return pNewMem;
2.为什么分配0个字节会返回(有效)内存地址?
documentation说明了LocalAlloc的返回值:
If the function succeeds, the return value is a handle to the newly allocated memory object.
If the function fails, the return value is
NULL
.
现在,只有当?uBytes为负时,LocalAlloc才会失败;它没有正值或零值的问题.
这意味着分配将始终成功?如果您尝试分配0个字节,您将始终收到有效指针.
?还有其他原因导致失败,例如:内存不足.为简单起见,他们在这个解释中被遗漏了.
3.我应该释放Marshal.AllocHGlobal(0)分配的内存吗?
LocalAlloc的签名是这样的:
DECLSPEC_ALLOCATOR HLOCAL LocalAlloc(
UINT uFlags,
SIZE_T uBytes
);
documentation说明了这一点
if [
uBytes
] is zero and theuFlags
parameter specifiesLMEM_MOVEABLE
, the function returns a handle to a memory object that is marked as discarded.
出于某种原因,Marshal.AllocHGlobal(0)不传递LMEM_MOVEABLE而是传递LMEM_FIXED.
文档缺少有关此特定案例的信息.运行测试(见下文)已经表明内存实际上正在被分配,你肯定需要释放内存,如下所示:
IntPtr zeroBytesPtr = Marshal.AllocHGlobal(0);
// Do stuff with the pointer.
Marshal.FreeHGlobal(zeroBytesPtr);
如果Marshal.AllocHGlobal改为传递LMEM_MOVEABLE,则不需要将指针释放到任何地方.
至于测试:
while(true) {
void* v = LocalAlloc(LMEM_FIXED, 0);
}
为循环的每次迭代分配内存,并且每次都返回一个新地址
while(true) {
void* v = LocalAlloc(LMEM_MOVEABLE, 0);
}
仅分配一次内存并每次返回相同的地址.
这表明为什么必须释放Marshal.AllocHGlobal分配的内存(因为它使用LMEM_FIXED),因为每次调用都会分配一个新的内存对象.
内容总结
以上是互联网集市为您收集整理的c# – Marshal.AllocHGlobal(0) – 为什么不返回IntPtr.Zero全部内容,希望文章能够帮你解决c# – Marshal.AllocHGlobal(0) – 为什么不返回IntPtr.Zero所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。