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


1.前言:

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


2.测试代码:

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

#include <vector>
#include <iostream>
using namespace std; int main() {
vector <int> 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下可以运行而且不出错

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



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

arr.begin() - 1**



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

visual studio

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

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

5.总结

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

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

  1. IOS文件操作的两种方式:NSFileManager操作和流操作

    1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...

  2. WCF 客户端调用服务操作的两种方法

    本节的主要内容:1.通过代理类的方式调用服务操作.2.通过通道的方式调用服务操作.3.代码下载 一.通过代理类的方式调用服务操作(两种方式添加代理类) 1.手动编写代理类,如下: 客户端契约: usi ...

  3. 安卓ListView操作的两种方法

    举例做一个微信的中间部分(好友消息等信息通知) 第一种:BaseAdapter() package com.example.wx; import java.util.ArrayList;import ...

  4. Dev控件删除按钮的两种方式

    测试版本15.2.10:在Dev控件中删除按钮空间有两种方式:1.鼠标右键出现Delete选项,这种删除是不完全的删除,只是删除了按钮的显示,实际上按钮还是存在于代码中的.2.用键盘上的Delete键 ...

  5. MySQL中删除数据的两种方法

    转自:http://blog.csdn.net/apache6/article/details/2778878 1. 在MySQL中有两种方法可以删除数据: 一种是delete语句,另一种是trunc ...

  6. 实例讲解Springboot整合MongoDB进行CRUD操作的两种方式

    1 简介 Springboot是最简单的使用Spring的方式,而MongoDB是最流行的NoSQL数据库.两者在分布式.微服务架构中使用率极高,本文将用实例介绍如何在Springboot中整合Mon ...

  7. spark-sql将Rdd转换为DataFrame进行操作的两种方法

    SparkConf sparkConf = new SparkConf() .setMaster("local").setAppName("ClzMap"); ...

  8. Eclipse中注释方法操作(两种)

    Eclipse 中的两种注释方法:(1)多行注释 /* */ (2)单行注释 // 多行注释操作方法. 选中注释部分-菜单栏右上角 source: Add block comment.必须选中需要注释 ...

  9. Delphi使用两种不同方法获取系统端口信息--(装载)

    Delphi使用两种方法获取windows系统的端口,还可测试发送消息,点击获取端口信息后,可依次得到如下信息:DCB结构大小.波特率大小.XON的临界值.XOFF的临界值.字符位数.奇偶检验位.停止 ...

随机推荐

  1. Ethical Hacking - GAINING ACCESS(22)

    CLIENT SIDE ATTACKS - BeEf Framework Browser Exploitation Framework allowing us to launch a number o ...

  2. Ethical Hacking - GAINING ACCESS(11)

    CLIENT SIDE ATTACKS - Listening for connections 1. Run Metasploit Move the backdoor file to the webs ...

  3. 足球动图gif(一)

  4. vue & 百度地图:在地图上绘制多边形

    <template> <div class="hello"> <div style="margin-bottom:10px"> ...

  5. Vue nextTick 学习历程

    nextTick 详解 这是官网的解释,比较简洁精炼,反正我是第一遍什么都没看懂 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 经过我一步步测试 ...

  6. vue的自定义指令。directive

    在vue中有很多vue自带的指令,比如v-heml.v-for.v-if,v-on.v-bind.v-else.v-show. 但是这些指令还不够我们使用的.就有了directive这个对象. 这个使 ...

  7. Image Processing Using Multi-Code GAN Prior, CVPR2020

    论文:Image Processing Using Multi-Code GAN Prior, CVPR2020 代码:https://github.com/genforce/mganprior 这是 ...

  8. 浅析MySQL中change与modify的区别

    MySQL版本 show variables like 'version'; 表结构 desc student; 修改表 例如:修改表student的name字段,将varchar(10)修改为var ...

  9. 数据库层级关系转换为树结构的json

    原文链接:https://blog.csdn.net/Tonysdyp/article/details/80987959 首先是数据库设计: 通过查询数据库,将全局数据作为一个ArrayList< ...

  10. springmvc的原理与流程

    springMVC中的几个组件: 前端控制器(DispatcherServlet):接收请求,响应结果,相当于电脑的CPU. 处理器映射器(HandlerMapping):根据URL去查找处理器 处理 ...