C++序列化容器(vector)中迭代化失效问题
insert导致的迭代器失效
void vector_test()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
vector<int>::iterator pos = find(v1.begin(), v1.end(), 3);
v1.insert(pos, 4);
print(v1);
cout << *pos << endl; //此处出现非法访问
}
会出现非法访问是因为insert之后pos迭代器已经失效,因为insert可能会导致容器增容,增容后会释放原来的空间,而迭代器pos依然指向原来空间中的位置,因此增容后pos将变为野指针。导致非法访问。
insert函数有一个返回值将返回插入后插入字符位置的迭代器
iterator insert (iterator position, const value_type& val);
例如用pos再接收insert的返回值:
void vector_test()
{
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
vector<int>::iterator pos = find(v1.begin(), v1.end(), 3);
pos = v1.insert(pos, 4);
print(v1);
cout << *pos << endl;
}
此时pos将指向插入数4的位置
erase导致的迭代器失效
void vector_test1()
{
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(a[0]));
vector<int>::iterator pos = find(v.begin(), v.end(), 3);
v.erase(pos);
print(v);
cout << *pos << endl; //迭代器失效导致的非法访问
}
迭代器失效是因为如果要删除的是vector的最后一个有效元素,则删除后pos指向vector中的非有效位置
因此,默认erase后,参数迭代器失效。对失效的迭代器访问时非法的。
但是同样erase也有返回值,返回删除位置的下一个位置。用例:
void vector_test1()
{
int a[] = { 1, 2, 3, 4 };
vector<int> v(a, a + sizeof(a) / sizeof(a[0]));
//删除v中的偶数
vector<int>::iterator it = v.begin();
while (it != v.end())
{
if (*it % 2 == 0)
{
it = v.erase(it); //删除后it会指向下一个位置
}
else
{
++it;
}
}
}