删除带有指针列表的对象并不能真正释放相应的内存

时间:2012-03-03 22:27:31

标签: c++ list pointers memory-leaks

我有一个类,其中包含与属性(Children)相同的类的对象的指针列表。我遇到的问题是,当我创建该类的对象时,向其添加子对象然后尝试删除它,它并没有真正释放内存(由系统监视器判断)。我正在使用Ubuntu和g ++。

下一个代码很好地说明了我的问题。它创建一个对象,向其中添加一千万个子对象然后将其删除。当我执行程序时,内存使用量从1.1增加到1.7 GB,即使在删除对象后它也会卡在那里。

¿有没有人知道发生了什么事?

非常感谢。

class UDVertex
{
  public:
   int ID;
   list<UDVertex *> Children;
};

void GetChildren(UDVertex * rootVT);

int main()
{
    UDVertex * MyVertex;

    MyVertex = new UDVertex;
    MyVertex -> ID = 0;

    GetChildren(MyVertex);

    while( ! MyVertex -> Children . empty() )
    {
         delete MyVertex -> Children . front();

         MyVertex -> Children . pop_front();
    }

    delete MyVertex;

    std::cout << "Press enter to continue...";
    std::cin.get(); 

    return 0;
}

void GetChildren(UDVertex * rootVT)
{
    UDVertex * Child;
    int i;

    for (i = 0; i < 10000000; i++)
    {
        Child = new UDVertex;
        Child -> ID = i + 1;

        rootVT -> Children . push_back ( Child ) ;

    }   

}

3 个答案:

答案 0 :(得分:1)

您的记忆已正确解除分配。但是,您的运行时库在删除后不会将您使用的内存返回到操作系统,因此系统监视器仍然会将您的进程视为已分配所有内存。

答案 1 :(得分:1)

这是完全正常的。虚拟内存不被视为稀缺资源,因此无需回收它。物理内存只有在需要用于其他目的时才能回收,因此不需要立即回收它。您需要使用更复杂的工具来确定虚拟内存是否已在进程内标记为空闲(以便可以重用)。这就是你应该关心的事情(除非你担心像碎片一样不寻常的事情)。

答案 2 :(得分:0)

问题是你测量记忆的方法 “系统监视器”监视分配给进程的内存(以巨大的块完成)。

在进程内,运行时库分配/回收内存(在new / delete之后);跟踪创建和删除的对象(与分配给进程的页面相比通常很小)。 “系统监视器”不会让您知道应用程序(您的应用程序的一部分)当前正在使用多少内存以及运行时保留的内容。

一个简单的测试是尝试再次分配对象(分配所有内存(check-size)释放所有内存(check-size)分配所有内存(check-size))。

如果内存使用量保持大致相同的大小(在每个检查大小),您知道已删除的对象已返回运行时并且现在已被应用程序重新获取,而进程不必向OS请求另一大块。