【发布时间】:2016-02-28 00:39:59
【问题描述】:
我有一个在具有 12GB 内存的 Windows 7 机器上运行的 c++ 程序。 编译器和链接器是 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)。
【问题讨论】:
-
你的分页文件有多大?
-
为什么在 C++ 程序中使用 realoc?你有一个遗留库可以与之交互吗?
-
你可能在混合堆吗?也就是说,如果您的缓冲区是由调试堆分配的,并且库是为发布而编译的,则每个模块将使用不同的堆。然后,库可能无法重新分配分配在它不管理的堆上的缓冲区。
-
@David Schwartz 页面文件大小是 windows 默认大小,我不记得数字了,也许我明天可以检查一下。但是由于在调用库函数之前我可以成功使用和释放 2.4GB 内存,我可以说有足够的“内存”(RAM+页面文件和 VA 空间)供操作系统提交吗?
-
@eran 我将库编译为静态对象文件(不是 dll)并在我的项目中使用了该库。所以我项目中的
realloc和编译库中的realloc使用不同的堆并且它们有不同的大小限制?如果这是真的,你知道如何让它们使用同一个堆吗?我检查了 MSDN,有一个关于堆大小 link 的链接器选项,它说“默认堆大小为 1MB”,这也让我感到困惑,因为我可以在不更改链接器选项的情况下分配 GB 的内存,但库代码可以使用
标签: c++ visual-c++ memory realloc