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

在循环中创建对象时内存泄漏 我是C++和内存管理的新手。我有一个代码,用于构建一个由类型为vertex(每个约100字节)和edge(每个约50字节)的对象组成的图。当图形很小时,我的代码工作得很好,但是对于具有~3M顶点和~10M边的实际数据,我得到了运行时错误:std::bad_alloc(当使用“new”(并且不总是使用相同的new)时),c++,memory-management,C++,Memory Management,根据我收集的信息,这是程序内存泄漏导致新内存分配失败的结果。我的问题是,我分配内存的方式有什么问题,更重要的是,我如何修复它。我大致是这样做的: 在graph类构造函数中,我为vertex类的对象创建数组存储库: graph:graph() { // vertexes is a class varaible vertexes = new vertex *[MAX_AR_LEN];// where MAX_AR_LEN = 3M } 然后我调用这样的函数来迭代地构建obj顶点并将它

根据我收集的信息,这是程序内存泄漏导致新内存分配失败的结果。我的问题是,我分配内存的方式有什么问题,更重要的是,我如何修复它。我大致是这样做的: 在graph类构造函数中,我为vertex类的对象创建数组存储库:

 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);
}
泄漏发生在哪里。我正在创建很多对象,但据我所知,没有任何对象可以删除或保持未删除状态。 我已经处理这件事一个多星期了,运气不太好。非常感谢你的帮助

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

  • 当处理大量需要同时存在于内存中的对象时,在编码之前,请使用最佳估计来找到所需的最小内存。在我的情况下,即使没有泄漏,我也几乎耗尽了内存。我只是需要更好地估计内存使用情况才能弄清楚这一点
  • 在开发代码的过程中,经常使用vld.h(或其他替代品)有助于检查您的设计是否没有内存泄漏。在最后这样做可能要复杂得多,即使你发现了泄漏,也可能更难修复
  • 假设您完成了所有这些操作,并且希望有足够的内存来运行代码,但是当系统上似乎有足够的可用内存时,会出现std::bad_alloc运行时错误。您可能正在为32位平台编译,切换到64位将允许从可用内存中分配更多内存
  • 这里很多人建议使用向量而不是数组,这是一种很有帮助的方法,可以避免常见的泄漏途径(以及其他便利),但假设内存泄漏,并且有数组。由于阵列不一定是泄漏的原因(显然),切换到矢量可能对您没有好处。不过,研究数组删除是一个良好的开端。以下是我收集的有关如何正确删除指向对象的指针数组的信息:
  • //假设我们有
    objType**objAr=新objType[aNum];
    
    对于(int i=0;i查看您使用
    new
    的次数。您使用它一次来分配指针数组(
    new vertex*[MAX\u aru LEN]
    )然后使用它
    v_num
    次来分配每个顶点。为了避免内存泄漏,您必须使用
    delete
    与使用
    new
    相同的次数,以便解除分配的所有内容

    您必须循环遍历指针数组,并在每个指针上执行
    删除顶点[i]

    但是,如果您使用了
    std::vector
    ,则不必处理这种手动内存分配,并且可以避免此类问题


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

    您不能
    删除顶点[i]
    ,只有顶点数组。这就是为什么您绝对应该使用
    std::vector
    。在@H2CO3的注释中,使用
    vector
    也可以使
    顶点的大小足够容纳真正需要的元素数量,而不是一些硬编码的最大大小(可能太大了)。谢谢您的回复!我下次肯定会尝试vectors,但这次我希望避免的事情需要进行大量的重组。我知道数组更容易出现问题,但不会天生导致泄漏。除了使用vectors重新编码,我能做些什么来用数组修复代码吗?@user3208953 you至少可以将
    顶点
    声明为
    顶点*vertex[MAX\u AR\u LEN]
    ,这样就不需要动态分配该数组(您仍然需要动态分配
    顶点
    s。计算您正在使用的
    s的数量,以及您正在使用的
    删除
    的数量。您很快就会注意到它们不在一起……感谢您的评论(以及拼写更正,我知道它看起来不正确)。我的理解是new被称为v_num times,delete[](与delete相反)调用析构函数fr数组中的所有元素。尽管如此,在到达我调用delete[]的点之前,运行中断。再次感谢您的回复。下次我将尝试使用vector作为我的第一选择。希望我能够在不进行vector中所需的重大调整的情况下修复代码(我已经过期了)。再次感谢!@user3208953
    delete[]
    不会为数组中的所有元素调用析构函数。它所做的是取消分配数组本身。由于您手动分配了每个
    顶点,因此必须遍历并取消分配它们。
    
     graph:~graph()
    {
      delete[] vertexes; 
      vertexes = 0;
    }
    
    //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;