C++之vector中元素删除

2015-01-27 14:19:38 · 作者: · 浏览: 37
今天在删除vector中的元素中遇到一个问题,这里记录下来以便以后查阅。
?
预备知识:用到了erase()函数,对于一个容器c来说,假设迭代器为p,那么执行:
?
c.erase(p)之后就删除了容器c中p所指向的元素,并且返回一个迭代器,返回的迭代器指向刚才所删除元素后面的一个元素(这里是关键)!
?
有了上面的知识后,我编写了下面的代码(头文件略去),删去矢量vals中的1:
?
复制代码
?1 int main()
?2 {
?3 ? ? vector vals;
?4 ? ? vals.push_back(1);
?5 ? ? vals.push_back(2);
?6 ? ? vals.push_back(2);
?7 ? ? vals.push_back(1);
?8 ? ? vals.push_back(2);
?9 ? ? vals.push_back(3);
10 ? ? vals.push_back(3);
11 ? ? vals.push_back(4);
12 ? ??
13 ? ? vector::iterator itr = vals.begin();
14?
15 ? ? while ( itr != vals.end())
16 ? ? { ? ?
17 ? ? ? ? if (1 == *itr)
18 ? ? ? ? {
19 ? ? ? ? ? ? vals.erase(itr);
20 ? ? ? ? }
21 ? ? ? ? else
22 ? ? ? ? ? ? ++itr;
23 ? ? }
24 ? ? itr = vals.begin();
25 ? ??
26 ? ? while(itr != vals.end())
27 ? ? {
28 ? ? ? ? cout << *itr << endl;
29 ? ? ? ? itr++;
30 ? ? }
31 ? ? return 0;
32 }
复制代码
?
?
?
?
?编译通过,但是调试就报错:
?
?
?
所以我进行了断点调试,发现第一个1可以成功删除,但是第二次试图遍历vals的时候,就会报错,看半天代码,无果,在网上搜了一些帖子,终于知道,原来,容器在删除或者插入一个元素之后,原来的迭代器会失效,于是第二次遍历时的判断条件还继续用原来的迭代器, 系统无法判断是什么东西,于是报错,怎么解决呢?但是C++设计者早就为我们铺好了路,虽然erase()使得原来的迭代器失效了,但是上面说过,erase()会返回一个迭代器,返回的迭代器指向刚才所删除元素后面的一个元素,于是我们就要利用好这个返回的迭代器,更改代码如下:
?
就是把上面代码中的第19行改为:
?
itr = vals.erase(itr);
?
?
这样,原来的迭代器失效了,但是返回的迭代器又重新赋给了itr,于是工作可以继续?
?
?
所以说看一百遍不如自己亲自实践一遍,看似简单的问题,没想到花了如此长的时间,事无巨细,实践为真!