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

Memory leakage when creating object in a loop

本文关键字:内存 泄漏 创建对象 循环      更新时间:2023-10-16

我是C 和内存管理的新手。我有一个代码,该代码是构建由类型顶点的对象组成的图(每个〜100字节)和边缘(每个字节〜50字节)。当图形很小时,我的代码正常工作,但是具有〜3M顶点和约10m边缘的真实数据,我会收到运行时间错误:STD :: BAD_ALLOC当使用" new"时)。

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

 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);
}

i然后完成其他任务,最后在程序结束之前,我有一个明确删除图对象

的破坏者
 graph:~graph()
{
  delete[] vertexes; 
  vertexes = 0;
}

泄漏发生在哪里。我正在创建很多对象,但据我所知,没有任何东西可以删除并保持未删除。我已经处理了一个多星期,但运气不多。非常感谢您的帮助!

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

  1. 在处理内存上需要同时存在的许多对象时,在编码之前,请先使用最佳估计来查找所需的最小内存。就我而言,即使没有泄漏,我几乎都会在记忆中最大化。我只需要更好地估算内存使用就可以弄清楚。
  2. 当您开发代码时,经常使用VLD.H(或其他替代方案)有助于检查您的设计是否没有内存泄漏。最后这样做可能要复杂得多,即使您发现泄漏,也可能很难修复。
  3. 假设您已经完成了所有这些,您希望有足够的内存来运行代码,但是当您的系统上似乎有很多免费内存时,您会得到STD :: BAD_ALLOC运行时间错误。您可能是为32位平台编译,切换到64位将允许从可用的内容分配更多内存(用于Visual Studio:)。
  4. 使用向量而不是许多许多人建议的数组是一种有用的方法,可以避免使用泄漏的通用途径(以及其他便利途径),但假设您有内存泄漏,并且有数组。由于数组不一定是泄漏的原因(显然),因此切换到向量可能无法为您服务。查看阵列删除是一个不错的开始。这是我收集的,以便如何正确删除对象的一系列指针:
//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()。只是这样做会导致内存泄漏。

查看您使用new的次数。您使用一次分配指针数组(new vertex *[MAX_AR_LEN]),然后使用它v_num次分配每个顶点。为了避免内存泄漏,您必须使用delete使用new的次数相同的次数,以便对分配的所有内容进行处理。

您将不得不循环遍历您的指针,并在每个指针上进行delete vertexes[i]

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

请注意,"顶点"的复数是"顶点"