美文网首页
vector erase 在windows与Linux下的不同

vector erase 在windows与Linux下的不同

作者: sf705 | 来源:发表于2017-09-25 21:36 被阅读60次

    昨天面试的时候,面试官突然问到这个问题,一面懵逼,感觉一样,回来试了一下,还真是不一样,做个小计。
    STL中,关于vector rease的源码如下(其中以清除某个位置元素函数为例):

    iterator rease(iterator position)
    {
        if (position + 1 != end())
            copy(position + 1, finish, position);
        --finish;
        destroy(finish);
        return position;
    }
    

    可以看到源码中返回的是一个迭代器类型,现在做一个测试,分别在windows和Linux下。

    Windows下的vector erase

    vector<int> ve = { 1, 2, 3, 4, 5 };
        for (auto iter = ve.begin(); iter != ve.end(); ++iter)
        {
            cout << *iter << endl;
            if (*iter == 3)
            {
                ve.erase(iter); //编译OK,运行会出现问题,迭代器失效
            }
        }
    

    因为运行时,发现3这个元素并删除,此时迭代器失效变成野指针,如果要是在遍历过程中继续处理后面元素可以这样写。

    vector<int> ve = { 1, 2, 3, 4, 5 };
        for (auto iter = ve.begin(); iter != ve.end(); ++iter)
        {
            cout << *iter << endl;
            if (*iter == 3)
            {
                ve.erase(iter); //出现野指针
                //方法1:返回删除元素的下一个位置,指向4,但是for中又有一个++,没有验证第四个元素
                //iter = ve.erase(iter);//返回删除元素的下一个位置
                //方法2:从头开始遍历
                //iter = ve.begin();
            }
            
        }
    

    如果想不跳过,也不从头开始,可以不在for中写++iter,而是在for大括号中写++iter,防止跳过删除元素后面的那个元素。

    在Linux下的vector erase

    同样的代码,发现有些不同,在windows下的野指针居然能通过,郁闷

    std::vector<int> ve = {1, 2, 3, 4, 5};
      for(auto iter = ve.begin(); iter != ve.end(); ++iter)
      {
        if(*iter == 3)
        {
          auto i = ve.erase(iter); //居然可以成功
          std::cout << "*i: " << *i << std::endl; //*i: 4
        }
      }
    

    相关文章

      网友评论

          本文标题:vector erase 在windows与Linux下的不同

          本文链接:https://www.haomeiwen.com/subject/mdodextx.html