map/set iterator not incrementablemap/set iterator not incrementable

use*_*855 13 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Expression:map/set iterator not incrementable
Run Code Online (Sandbox Code Playgroud)

当我按下忽略这个我得到

Expression:"standard c++ library out of range" && 0
Run Code Online (Sandbox Code Playgroud)

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

Jam*_*lis 13

如果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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

it = m_DriverList.erase(it);
Run Code Online (Sandbox Code Playgroud)


Ker*_* SB 11

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

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