##没有躲过的坑--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();
}));
~~~
- 前言
- deprecated关键字
- 指针(内存泄露)
- 头文件相互包含(Compiler error C2653: not a class or namespace name)
- 获取一张图片的width和height
- This function or variable may be unsafe.
- 智能指针陷阱
- wstring与string的转换
- windows下chrome浏览器插件不能安装
- 重定义关键字
- 正确释放vector的内存
- 获取设备环境HDC
- 抽象类不能实例化对象(但是你明明定义的不是抽象类)
- 重载赋值运算符的自我赋值
- 程序中的变量未初始化
- 成对使用new和delete时要采取相同的形式
- 意想不到的除数为零
- map的初始化(插入数据)
- 正则表达式截取字符串
- 捕获窗口之外的鼠标消息(钩子还是??)
- 类中的静态成员变量(static or const static)
- 有if就要有else(一定成对)
- map查找结果处理
- 使用using namespace std的坏习惯
- new一个指针数组、以及创建动态二维数组
- 使用太多的全局变量
- 没有及时break出for循环
- vector使用erase后迭代器变成野指针
- C++函数的默认参数(重新定义默认参数)
- 0xC0000005: 读取位置 xxx时发生访问冲突
- std::string初始化、最快速判断字符串为空
- 你开发的软件安装在C盘Program Files (x86)下产生的异常