1

这是我的代码:

void SurfaceManager::SurfaceManagerDelete()
{
    for(map<string,SurfaceManager*>::iterator Iter = SurfaceList.begin(); Iter != SurfaceList.end(); ++Iter)
    {
        delete (*Iter).second;

        (Iter) = SurfaceList.erase(Iter);
    }

   SurfaceList.clear();
}

为什么当我使用 VLD 扫描时会导致多次内存泄漏?我知道这与我从元素中删除内存的方式有关,特别是这一行“(Iter)= SurfaceList.erase(Iter);”,但是我想知道为什么,以及我应该如何从列表中正确删除元素。

4

2 回答 2

1

问题是for循环中的++Iter。那是因为

(Iter) = SurfaceList.erase(Iter);

已经更新 Iter 以指向擦除后的元素,如增量。

所以 ++Iter 然后跳过另一个元素,实际上你最终删除了所有其他元素!

于 2012-09-23T20:35:19.770 回答
1

您必须注意对正确的迭代器进行操作。++Iter在您的情况下,由于循环中的原因,您正在跳过一个迭代器for,有时您最终会调用++end 迭代器。

通常的变异关联容器循环是这样的:

for (auto it = m.cbegin(); it != m.cend() /* not hoisted */; /* no increment */)
{
    if (delete_condition)
    {
        // other stuff, like "delete it->second;"
        m.erase(it++);
    }
    else
    {
        ++it;
    }
}

或者,如果您要处理整个容器,请不要使用erase

for (auto & p : m) { delete p.second; }

// or alternatively

for (auto it = m.begin(); it != m.end(); ++it) { delete it->second; }

m.clear();

(我想指出,我clear()很少在容器上找到使用 for 。通常在 C++ 中,您的对象范围很窄,以便它们只存在最少的必要时间,当您需要新地图时,您只需创建一个新的,而不是清理和重新使用一个寿命太长的。)

于 2012-09-23T20:00:19.257 回答