在循环中创建对象时内存泄漏 我是C++和内存管理的新手。我有一个代码,用于构建一个由类型为vertex(每个约100字节)和edge(每个约50字节)的对象组成的图。当图形很小时,我的代码工作得很好,但是对于具有~3M顶点和~10M边的实际数据,我得到了运行时错误:std::bad_alloc(当使用“new”(并且不总是使用相同的new)时)
根据我收集的信息,这是程序内存泄漏导致新内存分配失败的结果。我的问题是,我分配内存的方式有什么问题,更重要的是,我如何修复它。我大致是这样做的: 在graph类构造函数中,我为vertex类的对象创建数组存储库:在循环中创建对象时内存泄漏 我是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: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);
}
泄漏发生在哪里。我正在创建很多对象,但据我所知,没有任何对象可以删除或保持未删除状态。
我已经处理这件事一个多星期了,运气不太好。非常感谢你的帮助
编辑(解决问题后):
谢谢大家的帮助。回顾过去,根据我提供的信息,很难确定到底发生了什么。我解决了问题,这里是我带走的非常明显的要点;很明显,这可能不值得分享,但无论如何,它们都在这里:
//假设我们有
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中所需的重大调整的情况下修复代码(我已经过期了)。再次感谢!@user3208953delete[]
不会为数组中的所有元素调用析构函数。它所做的是取消分配数组本身。由于您手动分配了每个顶点,因此必须遍历并取消分配它们。
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;