Home  >  Q&A  >  body text

c++ vector容器通过迭代器删除元素中奇数问题

vector中的元素{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
为什么使用下面的方法可以删除vector容器的偶数

for(auto vbegin = va.begin(); vbegin != va.end(); ++vbegin)
{
    if(!(*vbegin % 2))
    {
        va.erase(vbegin);
    }
}

而当使用类似的方法删除奇数时会报错代码如下,错误提示:Signal: SIGSEGV (Segmentation fault)

for(auto vbegin = va.begin(); vbegin != va.end(); ++vbegin)
    {
        if(*vbegin % 2)
        {
            va.erase(vbegin);
        }
    }
阿神阿神2715 days ago613

reply all(3)I'll reply

  • 大家讲道理

    大家讲道理2017-04-17 13:59:38

    The solution above assigns the iterator to begin() to achieve the effect, but it will restart the traversal every time, reducing efficiency. And another copy iterator will encounter out-of-bounds problems.
    This is my plan:

    {
        std::vector<int> vec = {1,2,3,4,5,6,7,8,9};
        auto itr = vec.begin();
        while (itr != vec.end()) {
            if (*itr % 2) {
                itr = vec.erase(itr);
            } else {
                itr++;
            }
        }//done
    } 

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 13:59:38

    C++ iterators become invalid after erasure,
    so the effect of va.erase(vbegin); after ++vbegin is executed is unknown.

    It is recommended to define a temporary iterator within the if block to delete container elements

    if( any condition about vbegin )
    {
        vector<int>::iterator element_to_delete = vbegin;
        ++vbegin;
        va.erase(element_to_delete);
    }

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 13:59:38

    Both are wrong, because the iterator will become invalid after the erase call, you need to

    va.erase(vbegin);
    vbegin = va.begin();

    Check the information to find out what happened with erase

    reply
    0
  • Cancelreply