c++ - 当内存可用时,realloc() 返回 NULL

标签 c++ visual-c++ memory realloc

我有一个 c++ 程序在具有 12GB 内存的 Windows 7 机器上运行。 编译器和链接器是 Visual Studio 2013 Express。

该程序使用 OGDF 库。 我将库源代码编译成具有 Release X64 配置的静态库,并在我的项目中引用了该库。

当我运行问题(调试 x64 配置)时,OGDF 库中的代码抛出异常,指示没有足够的可用内存;

    E *p = static_cast<E *>( realloc(m_pStart, sNew*sizeof(E)) );
    if(p == 0) OGDF_THROW(InsufficientMemoryException);

我暂停程序并打开调试窗口并检查了 sNew = 9M 和 sizeof(E) = 8 的值,因此分配了 72M 内存但失败了。

在调试时我打开了windows任务管理器,它显示我程序的内存使用(工作集大小和提交大小)小于2MB

所以我很困惑为什么 REALLOC 会失败,因为有足够的可用内存(>4GB)?即使我的堆中有很多碎片,提交的大小也小于 2MB,因此应该有足够的内存。

为了测试建议,我在调用库函数之前插入了以下代码:

void* ddd = malloc(1200000000);
char* b = (char*)ddd;
char ttt = 3;
int g = 0;
for (g = 0; g < 1200000000;++g)
{
    *(b + g) = ttt;
}
ddd=realloc(ddd, 2400000000);
b = (char*)ddd;
for (g = 0; g < 2400000000; ++g)
{
    *(b + g) = ttt;
}

上面的代码运行正常(调试 x64 配置)并且任务管理器显示我的内存使用量(工作集和提交大小)在我调用 free() 之前约为 2.3GB。所以在我的程序中我可以在我的堆上分配超过 2GB 的内存,为什么库代码中的 72MB 分配失败?

编辑:

我发现了问题。

当我使用发布配置编译的库文件时,调试器向我显示了错误的局部变量数据。实际原因是库正在调用 realloc(ptr,0)。

最佳答案

您的问题非常类似于“您为什么不给我开张 500 美元的支票?您银行里有 2,000 美元。”

操作系统在使用内存之前收到内存请求。操作系统无法批准内存分配请求,除非它有足够的后备存储来满足它已经允许的所有请求,无论它们当前是否正在使用任何 RAM。

例如,如果您malloc 1GB 但尚未访问分配的虚拟地址空间,则该分配将使用远少于 1GB 的 RAM。但在该分配被释放之前,系统必须保留 1GB 的后备存储(RAM 或交换),以防您的程序开始使用该分配的空间。

如果系统有太多这样的分配,即使它有足够的空闲 RAM,它也会拒绝新的分配。 Windows 不会过度使用,因为如果这些映射稍后需要比操作系统更多的后备存储,则存在强制终止应用程序的风险。

避免将来出现这些误解的一个好方法是避免单独使用“内存”这个词。如果您指的是 RAM,请说“RAM”或“物理内存”。如果您指的是后备存储,请说“后备存储”。如果您指的是地址空间,请说“虚拟内存”。

你说这样的话,“我有很多空闲内存,所以我应该可以分配内存。”这听起来像是一个谜。但是,如果您更准确地说,“我有很多空闲 RAM,为什么我不能分配更多虚拟内存(或后备内存)?”,您就已经回答了一半。

关于c++ - 当内存可用时,realloc() 返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33912861/

相关文章:

c++ - QFILE 用于 mediaSource 时 QT 声子播放失败,传递字符串时工作正常

C++/具有多个独立窗口的应用程序

c++ - 如何在 C 或 C++ 中获得与 Java 中的 toLowerCase 或 Python 中的 string.lower() 相同的结果?

c++ - 为什么范围解析在这里不起作用?

c++ - QObject::sender() 在插槽中无法正常工作

c++ - CUDA 设备端代码中的 C/C++ "inline"关键字

c++ - C++ 中的错误 C3867

java - 调试 NetBeans 模块时出现 OutOfMemory/PermGen 错误

c++ - 在 C++ 中,即使调用了 delete,进程什么时候会保留分配的内存?

c - 在 C 中,数组(即字符串)中的字符是存储在单独的寄存器中还是每个寄存器有四个字符?