关于vector的erase删除操作的两种不同方法,在linux与visual studio的实现讨论
关于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的实现讨论的更多相关文章
- IOS文件操作的两种方式:NSFileManager操作和流操作
1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...
- WCF 客户端调用服务操作的两种方法
本节的主要内容:1.通过代理类的方式调用服务操作.2.通过通道的方式调用服务操作.3.代码下载 一.通过代理类的方式调用服务操作(两种方式添加代理类) 1.手动编写代理类,如下: 客户端契约: usi ...
- 安卓ListView操作的两种方法
举例做一个微信的中间部分(好友消息等信息通知) 第一种:BaseAdapter() package com.example.wx; import java.util.ArrayList;import ...
- Dev控件删除按钮的两种方式
测试版本15.2.10:在Dev控件中删除按钮空间有两种方式:1.鼠标右键出现Delete选项,这种删除是不完全的删除,只是删除了按钮的显示,实际上按钮还是存在于代码中的.2.用键盘上的Delete键 ...
- MySQL中删除数据的两种方法
转自:http://blog.csdn.net/apache6/article/details/2778878 1. 在MySQL中有两种方法可以删除数据: 一种是delete语句,另一种是trunc ...
- 实例讲解Springboot整合MongoDB进行CRUD操作的两种方式
1 简介 Springboot是最简单的使用Spring的方式,而MongoDB是最流行的NoSQL数据库.两者在分布式.微服务架构中使用率极高,本文将用实例介绍如何在Springboot中整合Mon ...
- spark-sql将Rdd转换为DataFrame进行操作的两种方法
SparkConf sparkConf = new SparkConf() .setMaster("local").setAppName("ClzMap"); ...
- Eclipse中注释方法操作(两种)
Eclipse 中的两种注释方法:(1)多行注释 /* */ (2)单行注释 // 多行注释操作方法. 选中注释部分-菜单栏右上角 source: Add block comment.必须选中需要注释 ...
- Delphi使用两种不同方法获取系统端口信息--(装载)
Delphi使用两种方法获取windows系统的端口,还可测试发送消息,点击获取端口信息后,可依次得到如下信息:DCB结构大小.波特率大小.XON的临界值.XOFF的临界值.字符位数.奇偶检验位.停止 ...
随机推荐
- Spring Boot 2.x基础教程:使用EhCache缓存集群
上一篇我们介绍了在Spring Boot中整合EhCache的方法.既然用了ehcache,我们自然要说说它的一些高级功能,不然我们用默认的ConcurrentHashMap就好了.本篇不具体介绍Eh ...
- 将终结点图添加到你的ASP.NET Core应用程序中
在本文中,我将展示如何使用DfaGraphWriter服务在ASP.NET Core 3.0应用程序中可视化你的终结点路由.上面文章我向您演示了如何生成一个有向图(如我上篇文章中所示),可以使用Gra ...
- kotlin中使用Handler
kotlin中使用Handler jumpToPayHandler = Handler { var questionformModel = QuetionFormModel(2, spinner.te ...
- 前端 /deep/ 深入样式(很深入的那种哦) 简单收藏
简单介绍:使用vue脚手架和elemen-ui开发的前端项目 遇到这样的场景: 对div下的el-select下拉组件 设置样式,直接在标签上用style属性是完全可以的,但我们的开发规范是前端样式 ...
- 7个获取访问者真实IP的方法,速学!!!
通常情况下,网站访问并不是简单地从用户的浏览器直达服务器,中间可能部署有CDN.WAF.高防.例如,采用这样的架构:“用户 > CDN/WAF/高防 > 源站服务器” .那么,在经过多层代 ...
- 如何导入spring 的jar包到eclips
https://www.cnblogs.com/xxuan/p/6949640.html
- matplotlib绘制子图
fig,subs = plt.subplots(2,2) subs[0][0].plot(data_math_C1) subs[0][0].set_title('C_1 曲线') subs[0][1] ...
- == 和 is 的区别
import copy a = ['a','b','c'] b = a #b和a引用自同一块地址空间 print("a==b :",a==b) print("a is b ...
- Python os.chflags() 方法
概述 os.chflags() 方法用于设置路径的标记为数字标记.多个标记可以使用 OR 来组合起来.高佣联盟 www.cgewang.com 只支持在 Unix 下使用. 语法 chflags()方 ...
- PHP localtime() 函数
------------恢复内容开始------------ 实例 以一个数值数组和一个关联数组的形式输出本地时间: <?phpprint_r(localtime());echo "& ...