【发布时间】:2014-02-26 17:35:30
【问题描述】:
我是 C++ 和内存管理的新手。我有一个代码是建立一个由顶点(每个约 100 个字节)和边缘(每个约 50 个字节)类型的对象组成的图。当图形很小时,我的代码可以正常工作,但是对于具有 ~ 3M 顶点和 ~ 10M 边的真实数据,我得到运行时错误:使用“new”时的 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;
}
泄漏发生在哪里。我正在创建很多对象,但据我所知,没有任何可以删除且未删除的对象。 我已经处理了一个多星期了,但运气并不好。非常感谢您的帮助!
EDIT(解决问题后): 谢谢大家的帮助。回顾过去,根据我提供的信息,很难确定发生了什么。我解决了这些问题,这是我拿走的非常明显的要点;如此明显,可能不值得分享,但无论如何它们都在这里:
- 在处理需要同时存在于内存中的大量对象时,在编码之前使用您的最佳估计来找到您需要的最小内存。就我而言,即使没有泄漏,我也会几乎耗尽内存。我只是需要更好地估计内存使用情况来解决这个问题。
- 在开发代码时,经常使用 vld.h(或其他替代方法)有助于检查您的设计是否没有内存泄漏。最后执行此操作可能要复杂得多,即使您发现泄漏,也可能更难修复。
- 假设您完成了所有这些操作,并且您希望有足够的内存来运行代码,但是当您的系统上似乎有大量可用内存时,您会收到 std::bad_alloc 运行时错误。您可能正在为 32 位平台编译,切换到 64 位将允许从可用内存中分配更多内存(对于 visual studio: )。
- 这里很多人建议使用向量而不是数组是一种有用的方法,可以避免常见的泄漏路径(以及其他便利),但是假设您有内存泄漏并且您有数组。由于数组不一定是泄漏的原因(显然),切换到向量可能无法为您服务。看看数组删除虽然是一个好的开始。以下是我收集的关于如何正确删除指向对象的指针数组的内容:
//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()。只是做后者会导致内存泄漏。
【问题讨论】:
-
你没有
delete vertexes[i];,只有顶点数组。这就是为什么您应该绝对改用std::vector<vertex>。 -
添加到@H2CO3 的评论,使用
vector是否也可以使vertexes足够大以容纳真正需要的元素数量,而不是一些硬编码的最大大小(可能太大了)。 -
感谢您的回复!下次我肯定会尝试向量,但这次需要对我希望避免的事情进行大量重新洗牌。我知道数组更容易出现问题,但不会固有地导致泄漏。没有用向量重新编码,我能做些什么来用数组挽救代码吗?
-
@user3208953 您至少可以将
vertexes声明为vertex* vertexes[MAX_AR_LEN],然后您就不需要动态分配该数组(尽管您仍然需要动态分配vertexs。 -
计算您正在使用多少个
news,以及您正在使用多少个deletes。你很快就会发现它们没有加起来......
标签: c++ memory-management