美文网首页
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