为什么删除内存不可用? C ++

时间:2011-03-23 01:37:25

标签: c++ memory-management tinyxml

我有一个 200 MB XML文件,我使用 TinyXML 加载。我的问题是,当TinyXML对象被销毁时,它使用的内存将不会被重用。我使用过我在其他项目中使用的内存泄漏检测器,并且已经手动逐步执行代码并且无法找到任何内存泄漏,因此我不怀疑泄漏的内存是问题。

此代码将重现此问题:

#include <iostream>
#include <tinyxml.h>

int main()
{
    char* filename = "../LargeFile.xml";

    {
        TiXmlDocument targetDoc( filename );
        targetDoc.LoadFile();
    }

    char* buf = new char[ 524288000 ];
    delete [] buf;

    return 0;
}

使用Address Space Monitor我可以看到LoadFile()之后有一大块红色,然后在targetDoc被摧毁后它全部变黄。然后,当分配最终的char buf时,它显示为红色,但是在绿色空间的顶部,而不是从TinyXML中释放的黄色。如果尝试分配比绿色地址空间更多的缓冲区,应用程序将崩溃(内存不足)。这可以在下面的图片中看到。

After Load After Unload Char Buffer Allocation

根据地址空间监视器页面“自由地址空间以绿色显示,保留地址以黄色显示,已使用(已提交)内存区域以红色显示”那么为什么TinyXML释放内存根据地址空间监视器保留“reserved”。是什么导致这种情况发生,我该如何制止呢?

编辑:

“你在分配大缓冲区吗?如果是这样,那么黄色空间中可能存在内存碎片,并且无法分配大的连续缓冲区”

很好的问题但这表明TinyXML有内存泄漏,我的工具都没有显示出来。

更新

我做了循环,无休止地分配了int,最终似乎使用了所有的黄色空间。但是,更大的分配不使用它。这向我表明,在通过tinyXML解析xml文件期间,堆中出现了一些小漏洞,这些漏洞以一种方式对堆进行分段,使得只有小到足以容纳漏洞的对象才能在黄色空间中分配。所以我在TinyXML中搜索越来越长的漏洞,但仍未找到任何漏洞。一切似乎都得到了正确的释放,这让我回到了最初的困惑状态。

我无法解释这个问题。

Char Buffer Allocation Char Buffer Allocation2 Char Buffer Allocation3

2 个答案:

答案 0 :(得分:6)

您是否真的看到了内存问题的其他迹象?保留存储器表示从OS保留地址范围,但实际上没有物理存储器在使用。没什么值得担心的。当你下次需要记忆时,它将首先来自那个预留空间。

答案 1 :(得分:4)

当free()完成时,大多数操作系统实际上并没有将内存释放回操作系统(Linux有时用于大型解除分配)。相反,应用程序使用OS sbreak()函数来增加内存,保持“高水位线”。只要你为每个malloc()做free(),那么内存就不会被泄露,未来的分配将来自同一个内存。当然,可能是TinyXML内部的某些东西没有做这样的匹配,有意或无意地释放,例如:

  • TinyXML类中的某个函数,或者由它调用,可以有一个静态本地指针变量,在首次调用该函数时,该变量初始化为指向新分配的堆。如果在其他例程为更多瞬态数据分配了大量内存之后发生这种情况,那么即使在后一个内存被释放后,静态指针的分配也可能导致一些碎片,从而阻止在回收空间中分配一个巨大的连续块。