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
有没有人知道这里发生了什么:我会非常感激任何人的任何建议。感谢和热烈的祝福。
答案 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;
}
}