深入了解vector的erase

1、vector 的erase
看一下代码

#include<list>
#include<iostream>
#include<vector>
using namespace std;

int main()
{
	vector<int> ls;
	ls.push_back(1);
	ls.push_back(2);
	ls.push_back(3);
	vector<int>::iterator it = ls.begin();
	for ( it = ls.begin(); it != ls.end();)
	{
		if (*it == 2)
		{
			ls.erase(it);
		}
		else
		{
			cout << *it << endl;
			it++;
		}
	}

	return 0;
}

当执行 ls.erase(it); 之后,迭代器it 已经失效,虽然他指向的地址是对的,但是此时,编译器已经把it当做一个失效的迭代器,此时你再对it进行++,程序将会崩溃,改成以下代码
it = ls.erase(it);
此时erase后会返回一个新的有效的迭代器

erase源码和简单分析如下

    _CONSTEXPR20 iterator erase(const_iterator _Where) noexcept(
        is_nothrow_move_assignable_v<value_type>) /* strengthened */ {
        const pointer _Whereptr = _Where._Ptr;
        auto& _My_data          = _Mypair._Myval2;
        pointer& _Mylast        = _My_data._Mylast;

#if _ITERATOR_DEBUG_LEVEL == 2
        _STL_VERIFY(
            _Where._Getcont() == _STD addressof(_My_data) && _Whereptr >= _My_data._Myfirst && _Mylast > _Whereptr,
            "vector erase iterator outside range");
#endif // _ITERATOR_DEBUG_LEVEL == 2

//移动Nxt指针
        _Orphan_range(_Whereptr, _Mylast);
        //将后面数据整体往前移动
        _STD _Move_unchecked(_Whereptr + 1, _Mylast, _Whereptr);
        //销毁最后一个节点
        _Alty_traits::destroy(_Getal(), _Unfancy(_Mylast - 1));
        _ASAN_VECTOR_MODIFY(-1);
        --_Mylast;
        //返回一个新的迭代器
        return iterator(_Whereptr, _STD addressof(_My_data));
    }

综合以上正确的erase的用法如下

#include<list>
#include<iostream>
#include<vector>
using namespace std;

int main()
{
	vector<int> ls;
	ls.push_back(1);
	ls.push_back(2);
	ls.push_back(3);
	vector<int>::iterator it = ls.begin();
	for ( it = ls.begin(); it != ls.end();)
	{
		if (*it == 2)
		{
			it= ls.erase(it);
		}
		else
		{
			cout << *it << endl;
			it++;
		}
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值