map / set iterator not incrementablemap / set iterator not incrementable

时间:2012-01-25 03:31:47

标签: c++ visual-c++

Driver::~Driver()
{
    AutoCritSec acsDriverList(m_csDriverList,true);
    DRIVERLIST::iterator it = m_DriverList.begin();
    for(;it!=m_DriverList.end();it++) 
    {
        if (it->second == this) 
        {
            m_DriverList.erase(it);
            it = m_DriverList.begin();
        }
    }
}

当我在visual studio 2003中编译我的程序时,我的程序运行良好。但是当我在2010年做同样的事情,然后在关闭应用程序时我得到一些错误,如

Expression:map/set iterator not incrementable

当我按下忽略这个时,我得到了

Expression:"standard c++ library out of range" && 0

有没有人知道这里发生了什么:我会非常感激任何人的任何建议。感谢和热烈的祝福。

2 个答案:

答案 0 :(得分:14)

如果this是列表中唯一的元素,您将超出列表的末尾。

从列表中删除this后,您重置it = m_DriverList.begin();。这可以。然后评估循环表达式(i++语句中的for),这会导致it超出范围的末尾。

在容器末尾推进迭代器会导致程序显示未定义的行为。 Visual C ++的最新版本有助于在程序的调试版本中检测许多常见的迭代器错误,并引发断言以帮助您解决它们。

您可以通过删除循环表达式并将其移至else语句来解决此问题:

while (it != m_DriverList.end())
{
    if (it->second == this)
    {
        m_DriverList.erase(it);
        it = m_DriverList.begin();
    }
    else
    {
        ++it;
    }
}

但是,每次删除元素时重新启动迭代都是相当浪费的。请考虑使用调用erase

返回的迭代器
it = m_DriverList.erase(it);

答案 1 :(得分:9)

关联容器的正确擦除习惯用法如下:

for (auto it = container.begin(); it != container.end() /* not hoisted */; /* no inc. */ )
{
    if (delete_condition)
    {
        container.erase(it++);
    }
    else
    {
        ++it;
    }
}