如何正确删除向量中的对象

时间:2012-10-01 17:01:08

标签: c++ memory-leaks vector

在我的简单游戏引擎中,我有一个包含实体指针的向量。每个实体都分配有新关键字。要在我的实体上调用函数,我使用迭代器,所以当删除我的实体时,我想我也会使用迭代器,如下所示:

vector<Entity*>::iterator iter;
for (iter = gameEntitys.begin(); iter != gameEntitys.end();) {
    delete (*iter);
    ++iter;
}

但我现在有一个可怕的内存泄漏,所有分析工具都指向delete (*iter);

显然有一些错误,但是我删除向量中包含的实体(并清除另一个场景的向量)的正确方法是什么。使用gameEntitys.clear();对我来说毫无用处,因为它只删除了向量的元素,而不是实际上对它们进行删除,因为它们是指针而不是实际数据。

编辑:我看着评论。 Entity类不是多态的,也没有任何子类。如果我停止使用动态内存并且具有正常的非指针实体数组会更有意义吗?

我知道存在内存泄漏的原因是因为当应用程序启动时,内存使用率在崩溃之前会超过2gb。

1 个答案:

答案 0 :(得分:7)

最有可能的是,内存泄漏来自Entity或其子类之一的析构函数:您正在正确执行delete操作,因此析构函数本身必定是错误的。一个常见问题是没有在多态类层次结构中使析构函数成为虚拟。

你对调用gameEntitys.clear()的无用也是绝对正确的:它会通过“遗忘”对它们的引用来泄露你的对象“批发”。

如果您使用的是C ++ 11,请考虑将定义更改为使用std::unique_ptr

std::vector<std::unique_ptr<Entity> > gameEntitys;

这将使您无需手动管理条目的内存,同时让您在vector中保留指向派生类对象的指针。如果您使用unique_ptr,则对gameEntitys.clear()的调用将销毁向量元素指向的项目。

处理unique_ptr的向量有些不同(例如,插入新项目需要格外小心,详见this answer)但我认为简化内存管理的积极因素可以弥补轻微的不便

编辑:由于您的Entity类不是多态的,请考虑切换到std::vector<Entity>,除非您计划稍后切换到多态层次结构。