std::vector插入和删除进阶

【一】vector

删除元素

Std::vector<int> exampleVec = {1,2,3,4,5,6,7};

1. iterator erase( const_iterator pos )  //移除位于 pos 的元素

注意点】:

(1)迭代器 pos 必须合法且可解引用所以不能以 end() 迭代器为 pos 的值(合法,但不可解引用),不然会抛异常。

    比如:exampleVec.erase(exampleVec.end()); ----->程序向你抛出一个大大的异常,并且崩溃了

2. iterator erase( const_iterator first, const_iterator last )  //移除范围 [first; last) 中的元素

注意点】:

(1)  first==last ,则迭代器 first 不必可解引用

        比如:exampleVec.erase(exampleVec.end(), exampleVec.end());  --->合法的。原因参看下面第2

(2) 擦除空范围是无操作

   比如:exampleVec.erase(example.begin(),exampleVec.begin());   ---->无任何操作,元素还是1234567

 

返回值】:erase操作的返回值均为最后删除元素的下一个元素的迭代器,如果被删除的元素是最后一个元素,则返回的是end()迭代器。


删除元素迭代器失效问题

因为删除元素后,会导致该元素的迭代器失效,所以对vector循环遍历删除某些元素的时候,可能会有迭代器失效问题从而导致程序崩溃。

正确的做法是利用erase的返回值解决问题。下面是正确的示例,该示例演示删除vector中所有的奇数元素。

for (auto beg = exampleVec .begin(); beg != exampleVec .end();)  //不是在这里对beg++

{

        if (*beg % 2 != 0)

        {

                beg = exampleVec .erase(beg);  //在这里获取下一个元素

        }

        else

            ++beg;

} 

程序输出:2,4,6

 

插入元素

1. iterator insert( const_iterator pos, const T& value );  // pos 前插入 value

注意点:

(1) pos 可为 end() 迭代器

比如: exampleVec.insert( exampleVec.end(),8)  --->正确,则现在元素为:1,2,3,4,5,6,7,8

 

返回值】:insert操作的返回值都为第一个插入元素的迭代器

 

插入元素迭代器失效问题

因为插入元素后,后面的元素移动或者当前容量不够存放元素时候进行容量扩展的时候,迭代器会失效,所以对vector循环遍历插入某些元素时候,可能会有迭代器失效问题从而导致程序崩溃。

正确的做法也是利用insert的返回值。下面是正确的示例,该示例演示在vector中所有偶数元素后面插入一个数100

for (auto beg = vec.begin(); beg != vec.end();++beg)

{

        if (*beg % 2 == 0)

        {

            beg = vec.insert(++beg,100);         //如果仅仅写成vec.insert(++beg,100);则程序崩溃       

                                                                    //因为插入后,beg已经失效,再次进入循环时候++beg则异常崩溃

        }

} 

程序输出:1,2,100,3,4,100,5,6,100,7

总结:关于插入删除迭代器失效的问题,c++11中都使用插入/删除的返回值来获取正确的返回值。以上代码都经过vs2017测试运行。最后吐槽一下,网上好多博客内容都是一本正经的胡说。

猜你喜欢

转载自blog.csdn.net/qq_31175231/article/details/80854057