映射/迭代器增量错误

Map/iterator incremental error

本文关键字:错误 迭代器 映射      更新时间:2023-10-16

以下代码抛出调试断言映射/迭代器增量错误。

void ClassA::Remove()
{
    std::map<int, CVClassB*>::iterator it(m_p.begin());
    while ( it != m_p.end() )
    {
        if (it->first >= 0)
        {
            m_p.erase(it);
            it++;
        }   
    }
}

你能让我知道错误是什么吗

std::map::erase使

它操作的迭代器失效。因此,之后增加它是不安全的。但是erase()确实会为您返回下一个迭代器:

it = m_p.erase(it);

此外,你只在if递增it,所以除非所有的键都>=0,否则你会陷入无限循环。您可能想要这样的东西:

// delete all keys >= 0
if (it->first>=0) {
    it = m_p.erase(it); // erase and increment
}
else {
    ++it; // just increment
}

另外,正如弗拉德的回答所暗示的那样,谁管理CVClassB*的生命周期?你需要delete吗?为什么要使用指针,您可能可以直接将值存储在地图中。(或使用智能指针)。

像这样编写循环

while ( it != m_p.end() )
{
    if (it->first >= 0)
    {
        it = m_p.erase(it);
    }
    else
    {
        ++it;
    }
}

此外,您似乎应该删除擦除的迭代器指向的对象。例如

        delete *it;
        it = m_p.erase(it);

通过在循环内部删除来使迭代器无效,但无论如何,所做的只是清除映射。只需致电m_p.clear(),它就会完全按照您的要求进行操作。虽然不确定你想做什么是你打算做的,但这是另一个问题。

如果要删除指向的对象,请将其删除,然后清除地图。

for(item : m_p)
   delete item->second;
m_p.clear();
//done