没有躲过的坑--vector使用erase后迭代器变成野指针

vector上镜率非常高,但是最近又被他fuck了一下。使用的就是vector的erase方法。

erase–return value
首先需要明确一下vector的两种erase:

C++98中是这样的:

iterator erase (iterator position);
iterator erase (iterator first, iterator last)

C++11是这样的:

iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);

我们使用下面的代码进行erase:

#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> myvector;

  // set some values (from 1 to 10)
  for (int i=1; i<=10; i++) myvector.push_back(i);

  // erase the 6th element
  myvector.erase (myvector.begin()+5);

  // erase the first 3 elements:
  myvector.erase (myvector.begin(),myvector.begin()+3);

  std::cout << "myvector contains:";
  for (unsigned i=0; i<myvector.size(); ++i)
    std::cout << ' ' << myvector[i];
  std::cout << '\n';

  return 0;
}
/*-------------------------------------- Output: myvector contains: 4 5 7 8 9 10 ---------------------------------------*/

上面的代码非常的完美,但是当把ease用于for循环的时候,就完蛋了:

for(vector<int>::iterator iter=vector_database.begin(); vector_database!=veci.end(); iter++)
{
      if( *iter == 10)
      {
          vector_database.erase(iter);
      }
}

当执行veci.erase(iter)后,迭代器iter指向了哪里?

是时候关注一下erase方法的返回值了:

An iterator pointing to the new location of the element that followed the last element erased by the function call. This is the container end if the operation erased the last element in the sequence.

Member type iterator is a random access iterator type that points to elements.

看到random你就要疯掉了吧,野指针!!!!

也就是说veci.erase(iter)后,iter的状态是不确定的,再进行++,岂有不崩溃的道理!!

解决方法一,就是ease后对iter进行重新赋值。
解决方法二:再 使用一个迭代器。

vector<int>::iterator itor2;
for(vector<int>::iterator iter=vector_database.begin(); iter!=vector_database.end(); )
{
     if( *iter == 10)
     {   
           itor2=iter;
           vector_database.erase(itor2);
     }
      else
            iter ++ ;
}

remove or erase?
很多人还用到过remove,但是对于很多人不能分清楚remove和erase的区别?

STL中remove()只是将待删除元素之后的元素移动到vector的前端,而不是删除。若要真正移除,需要搭配使用erase()。

vector中的remove的作用是将等于value的元素放到vector的尾部,但并不减少vector的size

vector中erase的作用是删除掉某个位置position或一段区域(begin, end)中的元素,减少其size

erase with remove_if

vector_database.erase(
                std::remove_if(vector_database.begin(),
                    vector_database.end(),
                    [this](const unique_ptr<lesschat::Channel>& vector_database) {
                return this->current_channel_id_ == vector_database->channel_id();
            }));

你可能感兴趣的:(C++,remove,erase)