map/set iterator not incrementablemap/set iterator not incrementable

前端 未结 2 1881
-上瘾入骨i
-上瘾入骨i 2021-02-07 14:27
Driver::~Driver()
{
    AutoCritSec acsDriverList(m_csDriverList,true);
    DRIVERLIST::iterator it = m_DriverList.begin();
    for(;it!=m_DriverList.end();it++) 
    {
         


        
相关标签:
2条回答
  • 2021-02-07 14:56

    The correct erase idiom for associative containers is as follows:

    for (auto it = container.begin(); it != container.end() /* not hoisted */; /* no inc. */ )
    {
        if (delete_condition)
        {
            container.erase(it++);
        }
        else
        {
            ++it;
        }
    }
    
    0 讨论(0)
  • 2021-02-07 15:17

    If this is the only element in the list, you will overrun the end of the list.

    After you remove this from the list, you reset it = m_DriverList.begin();. This is fine. Then the loop expression is evaluated (the i++ from the for statement), which causes it to be advanced past the end of the range.

    Advancing an iterator past the end of the container causes the program to exhibit undefined behavior. Recent versions of Visual C++ helpfully detect many common iterator errors in debug builds of your program and raise assertions to help you to solve them.

    You can resolve the problem by removing loop expression and moving it into an else statement:

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

    Though, restarting iteration every time you remove an element is rather wasteful. Consider instead using using the iterator returned by the call to erase:

    it = m_DriverList.erase(it);
    
    0 讨论(0)
提交回复
热议问题