STL容器的删除元素问题
来源:互联网 发布:清华北大抢人 知乎 编辑:程序博客网 时间:2024/06/05 02:56
STL的容器分为两类,一类是序列式容器,即数据顺序连续存储,如:vector、deque;另一类是关联式容器,即数据不连续存储,如:map、list、set。对于STL容器的数据删除操作,有一些需要注意的地方。
1、序列式容器的数据删除
下面例子以容器list为例:
上面的代码,乍一看好像是没有什么问题,一个再普通不过的for循环而已,怎么会有问题呢?问题就是出在erase函数上了,对于关联式容器,erase函数会删除传入的迭代器指向的元素,并回收迭代器指向的内存空间,此时该迭代器已经失效。这下问题就清晰了,上面的代码若进行了erase操作后,迭代器iter已经失效了,而for循环的iter++接着会对一个已失效的迭代器iter进行++操作,这种操作不可预期,可能会造成程序crash。
正确的使用方法有以下两种:
方法一:
当erase函数执行完之后,会返回下一个有效节点,因此可以使用以下方法
方法二:
下面写法中,iter的后置++操作会完成两件事,第一是返回iter的一个副本,这个副本和iter本身都指向同一内存地址;第二是对iter自身进行了++操作,此时iter还是有效的,而且指向下一个有效节点。而副本则作为实参传给了erase函数,在erase函数中,副本所指的内存空间会被回收,副本会失效。可以简单理解为,在iter被删除之前就已经执行了++操作。
2、序列式容器的数据删除
对于序列式容器vector、deque的数据删除操作,也有一些点需要注意的,以vector为例,下面代码目标是删除vector中满足条件的数据:
我们期望的输出结果应该是:1 2 3 4 可是,上面代码实际输出结果却是:2 3 4,为什么会出现这种情况呢?这就涉及到容器vector本身数据结构的特点和erase()函数的作用问题了。由于vector是序列式容器,数据在其中是连续存储的,当调用了erase()函数删除其中的某个元素时,会将删除元素的下一个有效元素覆盖删除元素的所在位置的数据。
这下子,对于上面代码的输出结果就清晰了,当0元素被删除后,iter已经指向了1元素,而for循环的++iter操作则将iter再递增一次,使得iter指向了2元素,导致跳过了1元素,因此就出现了上面的输出结果了。假如有两个0元素连续存放,还会跳过第二个0元素的,导致没有完全过滤掉满足条件的数据,这个问题算是比较难发现的。
上面的代码可能会导致满足条件的数据没有被删除,但是在某些情况下,可能还会出现coredump问题,还是针对上面的例子,将上面代码的“过滤并打印数据”部分替换为以下代码,即删除值为4的数据:
二话不说,程序直接segmentation fault。当执行完erase之后,iter已经指向vec.end(),而for循环的++iter,再将iter递增一次,此时iter越界了,当执行*iter时,就导致了非法访问内存,程序crash。
- STL容器的删除元素问题
- STL容器的删除元素问题
- STL容器元素的删除
- STL 删除容器中元素的几个特殊问题
- 关于STL容器中vector特定元素的删除问题
- STL容器删除元素的陷阱(转)
- STL容器删除元素的陷阱
- 删除STL容器元素的方法
- stl容器遍历删除元素
- STL容器之 元素删除
- 安全删除STL容器元素
- STL容器中元素的删除的惯用法
- STL:循环删除容器中元素的方法和陷阱
- STL:循环删除容器中元素的方法和陷阱
- STL:循环删除容器中元素的方法和陷阱
- stl容器在循环遍历中删除元素的方式
- STL容器:在遍历的过程中删除元素
- STL序列式指针容器中删除元素的方法
- Linux for Ubuntu安装Inkscape开源矢量图工具
- vb.net 教程 12-2 HtmlDocument类 1
- C++ primer 第十六章笔记 初稿
- Bootstrap入门
- Java Web工作原理
- STL容器的删除元素问题
- HDU
- 待补充
- springcloud(二)
- Using System Calls
- solr-架构
- ありがとう
- 模型简单控制
- 如何在Linux上安装ftp组件