C++:iterator迭代器失效
说明:这里拿 vector 举例。
原因一:扩容导致迭代器失效
// 迭代器失效
void insert(iterator pos, const T& x)
{
assert(pos >= _start);
assert(pos <= _finish);
// 满了就扩容
if (_finish == _end_of_storage)
{
reserve(capacity() == 0 ? 4 : capacity() * 2);
}
iterator it = _finish - 1;
while (it >= pos)
{
*(it + 1) = *it;
--it;
}
*pos = x;
++_finish;
}
正确写法:
void insert(iterator pos, const T& x)
{
assert(pos >= _start);
assert(pos <= _finish);
// 满了就扩容,导致pos失效,失效后不能使用,更新后才能使用
if (_finish == _end_of_storage)
{
size_t len = pos - _start;
reserve(capacity() == 0 ? 4 : capacity() * 2);
pos = _start + len; // 更新pos
}
iterator it = _finish - 1;
while (it >= pos)
{
*(it + 1) = *it;
--it;
}
*pos = x;
++_finish;
}
原因二:insert后迭代器失效(野指针)
正确做法,最好是在insert之后不要使用它的迭代器!!!
原因三:erase后迭代器失效(强制检查)
// 迭代器失效
void erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);
iterator it = pos + 1;
while (it < _finish)
{
*(it - 1) = *it;
++it;
}
--_finish;
}
正确写法(系统的做法):系统erase(it)后,会返回删除值的下一个位置;但我们要记住,虽然可以这样解决,但是erase(it)之后,不要再去访问it迭代器,它已经失效了
iterator erase(iterator pos)
{
assert(pos >= _start);
assert(pos < _finish);
iterator it = pos + 1;
while (it < _finish)
{
*(it - 1) = *it;
++it;
}
--_finish;
return pos; // 下一个位置还是pos
}
完