-
java vector循环删除元素_STL Vector 的遍历删除. - Khan's Notebook GCC/GNU/Linux Delphi/Window Java/...
2021-02-28 10:43:37评论#re: STL Vector 的遍历删除.2009-12-08 18:43唐风>code3 错误的原因为, vecFiles.erase(it_pos); 当前的it_pos已经被删除>了, 再下一次循环的时候 it_pos++, 访问非法内存..>然后回过头来看code1, ...评论
# re: STL Vector 的遍历删除.
2009-12-08 18:43
唐风
>code3 错误的原因为, vecFiles.erase(it_pos); 当前的it_pos已经被删除
>了, 再下一次循环的时候 it_pos++, 访问非法内存..
>然后回过头来看code1, vecFiles.erase(it_pos++); 在当前的it_pos已经被
>删除的时候, it_pos已经指向下一个位置了. 虽然这里逻辑上是错误的. 但是利
>用c语法的特性产生了一个正确的结果, 算是一个技巧. 不算是一门技术.
我对这种的说法有不同看法:
it_pos无所谓删除不删除,it_pos 的行为就像指针一样,指针本身不会被删除,被删除的是指针指向的内容。我想楼主可能对迭代器失效的理解有偏差(建议在网上查一查相关的资料再看看)
我觉得,code1、2、3没有什么本质区别,都有可能产生迭代器失效的问题。
一个原则:对vector只要做了删除或是增加动作,就要示迭代器已经无效,必须重新从vector对象获取新的迭代器的值,而不能用临时变量、后缀自增等方法……
remove_if+erase的版本才是可读性最好且没什么问题的。
个人愚见,请博主笑纳……
回复 更多评论
# re: STL Vector 的遍历删除.
2009-12-10 10:23
梦芭莎内衣
傻傻的开发的 回复 更多评论
# re: STL Vector 的遍历删除.
2009-12-10 17:45
yisa
code1的做法: 对非连续内存容器是可行的 对连续内存容器是不可取的
code1中会出现漏删 而不是内存越界
回复 更多评论
# re: STL Vector 的遍历删除.
2010-06-25 16:04
glq
@yisa
我用代码验证了下,的确是这样:
欢迎去我的空间讨论交流 hi.baidu.com/bmrs
1 /*
2 DATE: 2010.6.25
3 内容:关于vector的遍历删除
4 任何改变 vector 长度的操作都会使已存在的迭代器失效。例如,在调用 push_back 之后,就不能再信赖指向 vector 的迭代器的值了。
5 */
6 #include
7 #include
8 #include
9 #include
10 using namespace std;
11
12 typedef vector V;
13 typedef vector::iterator VIT;
14 V v1;
15
16
17 int main()
18 {
19 for(int i=0; i<10; ++i)
20 v1.push_back(i);
21
22 VIT it = v1.begin();
23 VIT it2;
24 for(; it!=v1.end(); ++it)
25 cout<
26 cout<
27 VIT it0 = v1.begin()+1; // 1
28 it2 = v1.begin()+3; // 3
29 VIT it3 = it2+1; // 4
30 cout<
31
32 for(it=v1.begin(); it!=v1.end(); ++it)
33 {
34 if(*it == 3)
35 {
36 cout<
37 VIT tmp = it;
38 VIT r = v1.erase(it++);
39 cout<
40 cout<
41 cout<
42 if(r == tmp)
43 cout<
44 break;
45 }
46 }
47
48 cout<
49 return 0;
50 }
回复 更多评论
# re: STL Vector 的遍历删除.
2015-06-12 17:07
、开开
的说法是的范德萨阿士发送到发送到大夫阿士大夫士大夫士大夫撒大撒的 回复 更多评论
-
关于vector的erase删除操作的两种不同方法,在linux与visual studio的实现讨论
2017-04-25 10:19:31关于vector的erase删除操作的两种不同方法,在linux与visual studio的实现讨论1.前言:最近在做某一个题时,用到了vector的删除操作,利用的是erase()函数删除符合条件的函数,然后和同学讨论的时候,同学给了一个...#关于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说越界 -
在linux环境下,使用erase删除vector元素注意事项,删除的元素居然自动存放在改队列末尾
2020-07-02 15:54:12工作8年,第一次遇到这种问题,百思不得其解,使用erase删除vector元素,删除正常,但后面打印数据发现,元素居然依然存在。当然其实最终发现原因也是不注意代码细节引起的。先上代码。 注:以下代码在windows环境...工作8年,第一次遇到这种问题,百思不得其解,使用erase删除vector元素,删除正常,但后面打印数据发现,元素居然依然存在。当然其实最终发现原因也是不注意代码细节引起的。先上代码。
注:以下代码在windows环境直接报错,而linux居然正常输出。#include <iostream> #include <vector> using namespace std; int main() { std::vector<int> vec; for (int i = 0; i < 10; ++i) { vec.push_back(i); } vec.push_back(1); vec.push_back(1); vec.push_back(1); vec.push_back(1); for (auto it = vec.begin(); it != vec.end();) { cout << *it << endl; it++; } cout << "*************line******************" << endl; int nSize = vec.size(); for (auto it = vec.begin(); it != vec.end();) { if (1 == *it) { it = vec.erase(it); } else { ++it; } } auto it = vec.begin(); for (int n = 0; n < nSize;n++) { cout << *it << endl; it++; } system("pause"); return 0; }
在上输出数据:
看到没,删除的元素居然依然存在,其实是因为野指针原因引起的,由于编译器的差异,还真不一定会报错。
所以在开发过程中一定要注意细节,最后修改如下:#include <iostream> #include <vector> using namespace std; int main() { std::vector<int> vec; for (int i = 0; i < 10; ++i) { vec.push_back(i); } vec.push_back(1); vec.push_back(1); vec.push_back(1); vec.push_back(1); for (auto it = vec.begin(); it != vec.end();) { cout << *it << endl; it++; } cout << "*************line******************" << endl; for (auto it = vec.begin(); it != vec.end();) { if (1 == *it) { it = vec.erase(it); } else { ++it; } } //将size位置变动 int nSize = vec.size(); auto it = vec.begin(); for (int n = 0; n < nSize;n++) { cout << *it << endl; it++; } system("pause"); return 0; }
修改后输出如下:
-
linux的select实例
2020-05-04 12:35:43如果用vector管理所有文件描述符的话,一个描述符连接关闭删除复杂度较高。用set在Log复杂度删除,感觉更方便一点。 复杂度更低的一个思路: 开辅助数组/Vector存,再开一个数组存标志位(是否连接)。 //复用服务器...我用set存储文件描述符,复杂度会更高。
如果用vector管理所有文件描述符的话,一个描述符连接关闭删除复杂度较高。用set在Log复杂度删除,感觉更方便一点。
复杂度更低的一个思路:
开辅助数组/Vector存,再开一个数组存标志位(是否连接)。//复用服务器 #include <unp.h> #include <iostream> #include <set> #include <functional> #include <math.h> using namespace std; using namespace placeholders; typedef void (*func)(int,int); int main(){ int m_socket=socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_port=htons(60000); // cout<<addr.sin_port<<endl; addr.sin_addr.s_addr=htonl(INADDR_ANY); int tlen=1; if(setsockopt(m_socket,SOL_SOCKET,SO_REUSEADDR,&tlen,sizeof(tlen))<0){ perror("setsocket error"); exit(-1); } if(bind(m_socket,(SA*)&addr,sizeof(addr))<0){ perror("bind error"); exit(-1); } if(listen(m_socket,10)<0){ perror("listen error"); exit(-1); } int maxfd=0; fd_set allfd; timeval timeout{3,0}; set<int> s; s.insert(m_socket); while(1){ int now; FD_ZERO(&allfd); for(auto i:s){ FD_SET(i,&allfd); maxfd=max(maxfd,i+1); } switch(now=select(maxfd,&allfd,NULL,NULL,NULL)){ case -1: perror("select error"); exit(-1); case 0: break; default: if(FD_ISSET(m_socket,&allfd)){ int d_socket=accept(m_socket,NULL,NULL); if(d_socket<0){ perror("accept error"); exit(-1); } cout<<d_socket<<" 连接成功 "<<endl; s.insert(d_socket); maxfd=max(maxfd,d_socket+1); } for(auto i:s){ if(i==m_socket) continue; if(FD_ISSET(i,&allfd)){ cout<<i<<" 有数据到 "<<endl; char buf[1024]; int len=recv(i,buf,sizeof(buf)-1,0); if(len==0){ FD_CLR(i,&allfd); cout<<i<<" 关闭连接 "<<endl; s.erase(i); close(i); } else if(len<0){ perror("recv error"); exit(-1); } else{ buf[len]='\0'; cout<<buf<<endl; } } } } // cout<<now<<endl; } return 0; }
-
Linux多线程操作pthread_t
2019-10-30 17:12:12使用过 Boost 的哪些组件? 得到的答案大多集中在 vector、map 和 shared_ptr。 vector 或 map 的内部实现、各种...如何实现线程安全的引用计数,如何定制删除动作等等。 scoped_ptr、static_assert 等,这些库... -
C++map遍历删除数据(删除被2整除的键值对)
2019-08-02 20:23:29以前关于遍历删除本人都是使用一个vector来存储相关的key后,然后再删除,不过这样的效率确实不高,被朋友提点有效率好点的方法后,试了下以前以为会出错的方法,也对关联类的迭代器有了进一步认识吧,对这个迭代器... -
Linux C/C++ or 嵌入式面试之《C++ STL系列》(1) 序列式容器面试问题汇总
2020-08-29 15:06:35C++中vector和list的区别 vector和数组类似,拥有一段连续的内存空间。vector申请的是一段连续的内存,当插入新的元素内存不够时,通常以2倍重新申请更大的一块内存,将原来的元素拷贝过去,释放旧空间。因为内存... -
如何使用迭代器iterator循环删除容器中的元素?
2007-12-11 12:35:00STL中的容器主要分两类,一是顺序存储的,如vector;一是以红黑树形式存储的,如map。下面分别以vector和map为例,说明怎样利用迭代器在遍历的同时删除容器内元素。...// vector sample for Windows and Linuxin -
如何使用迭代器iterator循环删除容器中的元素?
2007-10-31 18:44:00STL中的容器主要分两类,一是顺序存储的,如vector;一是以红黑树形式存储的,如map。下面分别以vector和map为例,说明怎样利用迭代器在遍历的同时删除容器内元素。...// vector sample for Windows and Linuxin -
跨平台删除文件夹,拷贝文件夹,拷贝文件
2010-06-02 12:06:00为Windows和Linux平台。 #include #include #include #include #include #include <vector> #include #include #include #include #include <stdio -
map在循环时删除时,mm.erase( it++ ) 和 it=mm.erase( it ) 的区别
2013-10-12 17:29:37关于list,vector这类stl在for或者是while循环如果不做处理直接用erase(it)这种是会导致迭代器失效的事,想必已有很多人遇到了。不多解释,现在说一下我遇到的问题。 我的代码一般是写两个版本的,跨windows和... -
CVTE 面试总结
2021-01-08 15:28:11如果涉及到,你的利益,请及时联系我,我马上删除 1、CVTE一面电话57分钟 1、c语言预处理命令有什么 2、函数参数压栈顺序 3、结构体占据内存大小 4、指针与数组的区别 5、static关键字,全局变量局部变量作用域 6... -
面试常见汇总
2020-08-17 17:51:15如果比堆顶元素大,则删除堆顶元素,存入当前遍历到的数据,整个数据过程直到所有数据遍历完为止。 TOPK问题 vector扩容 vs下的是1.5倍扩容,Linux下因为要考虑到和内存管理的伙伴算法兼容,所以采用2倍扩容的方式... -
记录VINS-Mono程序中的C++库和语法,查缺补漏
2020-05-18 19:52:18std::vector 转载地址:http://blog.csdn.net/w_linux/article/details/71600574 一、定义 强化版数组,封装了动态大小数组的顺序容器。容器类型都可以存放任意类型的对象。向量是一个能存放任意类型的动态数组。 二... -
新版Android开发教程.rar
2010-12-14 15:49:11• Linux (tested on Linux Ubuntu Dapper Drake) Supported Supported Supported Supported Development Development Development Development Environments Environments Environments Environments Eclipse IDE o... -
我的第一本C++书 游历C++世界的地图 PDF 电子书
2012-06-03 19:14:2010.5.2 删除容器中的冗余元素 第11章 函数指针、函数对象与Lambda表达式 11.1 函数指针 11.1.1 函数指针的声明与赋值 11.1.2 用函数指针调用函数 11.1.3 用函数指针实现回调函数 11.1.4 将函数指针... -
PaperTest Q&A笔试综述
2021-02-10 19:00:291) Vector.… 44 2]upper_ bound&lower_bound 45 mAp 45 数据结构 46 1.树. 146 1)基本知识 …46 2)几个问题 46 3)完全二叉树( Complete binary tree)… 54 4)次优查找树 55 5)最优二叉树霍大... -
面试官问我同步容器(如Vector)的所有操作一定是线程安全的吗?我懵了! 全网最透彻HTTPS(面试常问) 枚举 我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了 Java 集合框架看这一篇就够了 Java 集合中「...
-
最权威的C++教程_C++_Primer_Plus中文第五版+C++_Primer中文第四版(都含源码+习题)(共4分卷)分卷1
2010-06-23 17:33:55书中的范例在Windows XP系统、Macintosh OS X系统和Linux系统上进行 了测试。只有为数不多的几个程序会受编译器不兼容问题的影响。本书前一版面世后,编译器在遵循C++标 准方面更严格。 对于本书中完整的程序,... -
最权威的C++教程_C++_Primer_Plus中文第五版+C++_Primer中文第四版(都含源码+习题)(共4分卷)分卷2
2010-06-23 17:47:19书中的范例在Windows XP系统、Macintosh OS X系统和Linux系统上进行 了测试。只有为数不多的几个程序会受编译器不兼容问题的影响。本书前一版面世后,编译器在遵循C++标 准方面更严格。 对于本书中完整的程序,... -
最权威的C++教程_C++_Primer_Plus中文第五版+C++_Primer中文第四版(都含源码+习题)(共4分卷)分卷3
2010-06-23 18:03:39书中的范例在Windows XP系统、Macintosh OS X系统和Linux系统上进行 了测试。只有为数不多的几个程序会受编译器不兼容问题的影响。本书前一版面世后,编译器在遵循C++标 准方面更严格。 对于本书中完整的程序,... -
QuickLib(期货行情、交易库Python CTP程序化例子源代码) 2.05
2016-12-16 13:04:20删除了2个不成熟的例子,并简化了配置文件中的字段 2016.9.21 Quicklib(期货行情交易接口) 1.61 (1)更新库兼容性 (2)增加了查询持仓的函数方法(包括 今日多单、非今日多单、今日空单、非今日空单、总多单、总空单... -
存在一个全局的的RunNode栈root(实际是std::vector),会从下到上依次画出每个节点。RunNode类有一个占满全屏的属性,表示这个类将占用全部的屏幕,因此引擎在绘制的时候,会仅找出最靠上的含有该属性的节点,并从...
-
Oracle DBA突击:帮你赢得一份DBA职位--详细书签版
2013-02-06 15:56:403.7.1 改动向量(Change Vector) 112 3.7.2 Redo记录 112 3.7.3 检查点 115 3.7.4 SCN号 116 3.7.5 数据库恢复 118 3.7.6 恢复过程 120 3.8 Oracle MAA介绍 123 3.9 小结 125 第4章 OEM 126 4.1 ... -
Java面试宝典2010版
2011-06-27 09:48:2713.删除除了id号不同,其他都相同的学生冗余信息 14.航空网的几个航班查询题: 15.查出比经理薪水还高的员工信息: 16、求出小于45岁的各个老师所带的大于12岁的学生人数 17.求出发帖最多的人: 18、一个用户表中...
-
项目管理工具与方法
-
【Redis】Java操作Redis:Jedis 基本操作及连接池
-
华为机试 质数因子
-
IDEA远程调试SpringBoot项目.pdf
-
基于springboot实现表单重复提交.docx
-
linux nvidia-smi 执行速度很慢问题解决
-
json处理jar包合集.zip
-
USBQD_V3.0_XiTongZhiJia.rar
-
基于对偶四元数的姿轨耦合动力学模型1.md
-
realsense D435i传感器视觉模组测评(不严谨测评)
-
深究字符编码的奥秘,与乱码说再见
-
dfs递归实现组合型枚举
-
jdk-9.0.4_Wind-x64.zip
-
py课程设计.zip
-
PKI&ID.pptx
-
【爱码农】C#制作MDI文本编辑器
-
银行专业术语解释说明 超级详细
-
MySQL Router 实现高可用、负载均衡、读写分离
-
在 Linux 上构建企业级 DNS 域名解析服务
-
文件操作所需Jar.zip