linux的vector的删除数据,关于vector的erase删除操作的两种不同方法,在linux与visual studio的实现讨论...

#关于vector的erase删除操作的两种不同方法,在linux与visual studio的实现讨论

##1.前言:

最近在做某一个题时,用到了vector的删除操作,利用的是erase()函数删除符合条件的函数,然后和同学讨论的时候,同学给了一个写法,网上也搜到了一个写法,但是发现了问题。

##2.测试代码:

定义一个vector 删除指定元素, 这里是删除1

#include

#include

using namespace std;

int main() {

vector arr;

arr.push_back(1);

arr.push_back(2);

arr.push_back(3);

arr.push_back(4);

arr.push_back(5);

for (auto i = arr.begin(); i != arr.end(); i++) { // 第一种写法

if (*i == 1) {

i = arr.erase(i);

i--;

}

}

for (auto i = arr.begin(); i != arr.end();) { // 第二种写法

if (*i == 1) {

i = arr.erase(i);

} else {

i++;

}

}

for (auto i = arr.begin(); i != arr.end(); i++) { //输出

cout << *i << " ";

}

cout << endl;

return 0;

}

##3.讨论

这两种写法, 看起来是基本相同的,基本想法就是每一次循环 删除了迭代器那么不自增迭代器,反之,则自增迭代器, 实则不然,如果一上来就删除首元素, 那么问题就来了 方法一的i在自减之后不是出了小于arr.begin()了吗。别急我们看下面的实践。

##4.测试

ubuntu

在ubuntu下可以运行而且不出错

b71bd9a0424fcc25cc780732775e6a5d.png

这里进入gdb调试 查看迭代器i的变化

299c6d6ebc3edffdcd4b363703eee59d.png

在删除元素后 迭代器自减后竟然是有地址的 此时地址是arr.begin()的前面一个地址, 也就是说i可以变成

arr.begin() - 1

3959d22d045e9842cfb555182b3d5e6b.png

迭代器自加后 迭代器变成了arr.begin()

68ed2d53f0f49f0bdcb1e8e95d35d421.png

###visual studio

运行时错误,出错在 i–;

因为i–后 i变成了arr.begin() - 1 而visual studio不支持这样的写法,所以报错

017366e3c2b93a3df4d11ece5e25510f.png

b245ddc0f6c0922403f4469610562e71.png

##5.总结

vector如果简单想象成数组arr的话,在首元素i–,i = (arr - 1),但我们并没有在这个状态下解引用。然后i++加回去又回到可解引用的地址值,不出事也是可以理解的, gnu对list的实现是双向循环链表 ++list.end() 后就变成 list.begin()。但vs会assert说越界

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值