为什么malloc总是返回NULL

6

我的开发环境是VS2008、DX9和Windows XP。

我试图在内存不足的情况下添加保护处理。当malloc返回NULL时,我会将一些资源分页到磁盘上,并释放内存中的资源。

但有时候,即使我释放了大部分资源并且任务管理器中的进程内存使用率和VM大小仅为800MB,malloc仍然总是返回NULL。

我认为在进程内存使用率只有800MB的情况下,使用malloc分配88字节应该没有问题。但malloc总是返回NULL。

这可能是内存碎片化吗?看起来不像,因为进程内存使用率并不太高。

alt text http://i.imagehost.org/0267/Snap2.jpg


Exe已被VS调试器启动并附加。 - Buzz
void* AllocCRT(size_t size) { return malloc(size); }内存使用量:644,088K 虚拟内存大小:671,064K - Buzz
即使我释放了所有资源,malloc仍然无法工作。这是HeapAlloc的错误吗??? - Buzz
3个回答

2
您提到了内存碎片问题,这很可能是问题的原因。您可以尝试下载名为“地址空间监视器”的应用程序,它可以显示是否存在碎片问题。请访问此链接以下载该应用程序。

1
这个监视器将分析操作系统所看到的进程地址空间,而MSVC中的malloc是通过Windows Heap API工作的。它不会直接从系统中分配内存,也不会直接将其返回给系统。这意味着这个监视器将无法为您显示任何内容。对于这样的监视器来说,整个程序堆看起来就像一个坚固的、不可穿透的永久分配内存的黑盒子。 - AnT stands with Russia
@AndreyT:我认为“不会显示任何内容”有点过了。进程堆使用用户地址空间,因此您可以看到何时已耗尽该空间;这并不一定意味着malloc无法分配堆已经保留的内存。它应该在有可用地址空间时表现出来,如果需要分配比已经保留的内存更多的内存,则堆应该能够声明该空间。 - CB Bailey

2

可能是虚拟地址空间的碎片化。一种检查方法是调用HeapCompact(GetProcessHeap(), 0)。如果这样能够释放足够的内存,那么这很可能是原因。

另一个类似的原因是从调试器启动;这会导致Windows使用调试堆,长时间使用会导致非常糟糕的内存行为。为了禁用这种行为,在环境中设置_NO_DEBUG_HEAP=1并运行。


0
另一个可能性是你的程序中可能存在错误。你认为你正在请求88个字节,但也许你正在传递一个未初始化的变量并请求数百兆字节。或者也许你之前做过的某些事情超出了缓冲区并破坏了堆,导致malloc()在此之后永远失败。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接