在循环中创建对象时的内存泄漏

时间:2014-02-03 09:40:05

标签: c++ memory-management

我是C ++和内存管理的新手。我有一个代码,用于构建一个由顶点类型(每个约100个字节)和边(每个约50个字节)的对象组成的图形。我的代码在图形较小时工作正常,但是对于具有~3M顶点和~10M边缘的实际数据,我得到运行时错误:std :: bad_alloc当使用“new”时(并不总是使用相同的新) )。

根据我收集的内容,我的程序中的内存泄漏会导致新内存分配失败。我的问题是我分配内存的方式有什么问题,更重要的是我如何解决它。这大致是我做的: 在图类构造函数中,我为类顶点的对象创建了数组存储库:

 graph:graph()
{
   // vertexes is a class varaible
   vertexes = new vertex *[MAX_AR_LEN];// where MAX_AR_LEN = 3M
}

然后我调用这样的函数来迭代地构建obj顶点并将它们分配给数组。

 void graph::buildVertexes()
{
    for(int i=0; i<v_num; i++)
       vertexes[i] = new vertex(strName);
}

然后我完成了其他任务,最后在程序结束之前我有一个显式删除图形对象的析构函数

 graph:~graph()
{
  delete[] vertexes; 
  vertexes = 0;
}

泄漏发生在哪里。我正在创建很多对象,但据我所知,这些对象可能被删除并且仍未删除。 我已经处理了这个问题一个多星期了,运气不好。非常感谢你的帮助!

编辑(解决问题后): 谢谢大家的帮助。回顾过去,根据我提供的信息,很难确定发生了什么。我解决了这些问题,这是我带走的非常明显的一点;很明显,可能不值得分享,但无论如何它们都在这里:

  1. 在处理需要同时存在于内存中的大量对象时,在编码之前使用最佳估计来查找所需的最小内存。在我的情况下,即使没有泄漏,我几乎会记忆力。我只需要更好的内存使用估计来解决这个问题。
  2. 在开发代码时,经常使用vld.h(或其他替代方法)可以帮助检查您的设计是否没有内存泄漏。最后这样做可能会复杂得多,即使您发现泄漏,也可能更难修复。
  3. 假设你做了所有这些并且你希望有足够的内存来运行代码但是当你的系统上有足够的可用内存时你会得到std :: bad_alloc运行时错误。您可能正在编译32位平台,切换到64位将允许从可用的内容中分配更多内存(对于visual studio:)。
  4. 使用向量而不是像许多人所建议的那样是一种有用的方法来避免泄漏的常见路径(以及其他方便),但是假设你有内存泄漏并且你有阵列。由于数组不一定是泄漏的原因(显然),切换到矢量可能不适合你。看看数组删除虽然是一个好的开始。以下是我为如何正确删除指向对象的数组而收集的内容:
  5. //Let's say we have
    objType **objAr = new objType[ aNum];  
    for(int i=0; i<objNum; i++)
    {
        ObjAr[i] = new objType();
    }
    // to delete:
    for(int i=0; i<objNum; i++)
    {
        delete objAr[i];
    }
    // If instead of array of pointers we had just
    // an array of objects loop wasn't needed
    delete [] objAr; 
    objAr = 0;
    

    具有讽刺意味的是,我的代码中的泄漏源是不正确地删除了指向对象的指针。对于向量,我需要首先逐个元素删除,然后执行vec.clear()。只是做后者导致内存泄漏。

1 个答案:

答案 0 :(得分:2)

查看您使用new的次数。您只需使用一次来分配指针数组(new vertex *[MAX_AR_LEN]),然后使用它v_num次来分配每个顶点。为避免内存泄漏,您必须使用deletenew相同的次数,以便释放所分配的所有内容。

你将不得不循环遍历指针数组并在每个指针上执行delete vertexes[i]

但是,如果您使用了std::vector<vertex>,则不必处理此手动内存分配,并避免出现这些问题。

请注意,“顶点”的复数是“顶点”