关于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的临界值.字符位数.奇偶检验位.停止 ...
随机推荐
- Python Ethical Hacking - KEYLOGGER(1)
A program that records keys pressed on the keyboard. Common features: Store logs locally(local keylo ...
- 微信小程序-点餐系统
一.前言说明 博客声明:此文链接地址https://www.cnblogs.com/Vrapile/p/13353264.html,请尊重原创,未经允许禁止转载!!! 1. 主要功能 (1)后台定义分 ...
- Java7/8 中的 HashMap 和 ConcurrentHashMap
Java7 HashMap 数组+链表 Java7 ConcurrentHashMap Segment数组+HashEntry数组链表+ReenTrantLock分段锁 Java8 HashMa ...
- web自动化 -- ActionChains()的鼠标操作
webdriver模块下的ActionChains类 一.两个主要组件 1.实例化 ActionChains() 2.ActionChains(driver).perform() perform() ...
- Mybatis(三)动态sql语句
动态sql语句操作 1.MyBatis中#{ }和${ }的区别 在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析.mybatis 为我们提供了两种支 ...
- jsp课堂笔记4 javabean
Javabean是一个可重复使用的软件组件,实际上是一种java类 实现代码重复利用 易编写易维护易使用 jsp页面的主要任务是显示页面,不负责数据的逻辑业务处理 将数据处理过程中指派一个或多个bea ...
- 如何使用Excel管理项目?
1.什么是复杂问题? 复杂问题需要很多道工序,涉及到与多个人进行沟通,人的注意力没法持续关注,导致很容易忘掉很多重要步骤.像这种问题就要用到项目管理工具,在重要的节点上,来检查自己是否遗漏了重要的环节 ...
- C#怎么统计网站当前在线人数
1.问题背景 c#网站怎么合理的统计在线人数?我想通过全局变量来统计软件的使用情况,当启动软件时向服务器的用户表写开始使用时间,正常退出时写一个结束使用时间,来统计用户的在线使用情况. 但是有一个问题 ...
- TCP 服务器端
""" 建立tcp服务器 绑定本地服务器信息(ip地址,端口号) 进行监听 获取监听数据(监听到的客户端和地址) 使用监听到的客户端client_socket获取数据 输 ...
- Python os.fchmod() 方法
概述 os.fchmod() 方法用于改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限.高佣联盟 www.cgewang.com Unix上可用. 语法 fchmo ...