Visual Studio 2010 C++:malloc()/HeapAlloc 总是为最小的分配大小分配新页面

Posted

技术标签:

【中文标题】Visual Studio 2010 C++:malloc()/HeapAlloc 总是为最小的分配大小分配新页面【英文标题】:Visual Studio 2010 C++: malloc()/HeapAlloc always allocates new page for even smallest alloc size 【发布时间】:2014-12-09 19:15:12 【问题描述】:

我有一个相当大的 C/C++ 项目,我一直在试图找出它消耗过多内存的原因(由任务管理器中的“工作集”判断)。 我终于找到了一个奇怪的行为,即使对于最小的 malloc() 请求,它也会分配一个全新的 4k 页面。 像这样的代码

    for(int bla = 0; bla < 1000; bla++)
    
        char* blu = (char*)malloc(10);
    

这应该会增加 10KB 的内存消耗,但最终会增加 4MB,因为它分配了 1000 个 4kB。

真正令人沮丧的部分是我无法将其复制为独立的。仅使用上述代码的小应用程序就可以正常工作。只有大项目表现出错误的行为。 提前回答一些明显的建议:

我正在拉入与大项目相同的库,并确保编译标志相同

“new”的行为方式相同

在调试和发布模式下都会发生这种情况

我确实追踪到了 HeapAlloc 调用,这是罪魁祸首。遗憾的是,无法进入 HeapAlloc 进行进一步调查。

有什么想法吗?我完全被难住了。

【问题讨论】:

仅供参考,无论谁正在阅读此问题及其稍后的答案,这不是问题(这是堆页面问题)。调试堆可以对内存分配进行“填充”以检测缓冲区溢出/不足,但它永远不会像页堆那样将内存分配膨胀 1000 倍。 【参考方案1】:

Windows 包含一个名为“Page Heap”的功能,它有助于定位内存损坏缺陷。它通过将每个分配放在一个页面上进行操作,如果程序损坏内存而不是进入未定义的行为区域,这会导致处理器发出访问冲突。

听起来好像有人在您的大型应用程序中的某个地方打开了页面堆,或者您在 Windows 中触发了启用页面堆的大型应用程序中的某种应用程序兼容性设置。

请注意,这是 Windows 设置(HeapAlloc 是 Win32 API),而不是调试/发布编译器设置。

【讨论】:

哇,感谢您的回复一百万!最后实际上是一个注册表问题,我的应用程序被标记为启用了页面堆。删除注册表项后,它现在可以正常工作了。

以上是关于Visual Studio 2010 C++:malloc()/HeapAlloc 总是为最小的分配大小分配新页面的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2010 像 Visual Studio 6 一样在 C++ 中编译内联程序集?

visual studio2010 c++头文件怎么写

Visual Studio 2010 的 Visual C++ 2012 运行时库先决条件

如何将项目从 Visual C++ 6.0 转换为 Visual Studio Express 2010?

Visual c++ 6.0 应用程序大小大于 Visual Studio 2010 应用程序大小

无法在 Visual Studio 2010 中构建 C++ 项目