检验vector::iterator在push了N元素后的有效性

cxjddd 2003-06-11 04:00:59
对于那些iterator会不会失效、会在什么时候失效一直不太明白。于是就想自己验证一下。第一个动手的是vector的iterator。
  我的方法是:
  先push一个0,记录begin()值和begin()元素的值。
  然后,从1开始push,使vector一定要重新分配内存。这样没有两个元素相等。
  再就开始比较:从begin()到end(),找是否有与原来的begin()相等并且也指向0的。如果有,表示原来的iterator有效;没有,则原来的iterator已经失效了。
  我测试的结果是“失效”。
  不知我的方法对不对。我想是很不完善的。

  我想得到完整的关于iterator的“时效性”问题的答案。请各位说说吧。

#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;

int main ()
{
vector<int> vec;
vec.push_back (0);
vector<int>::const_iterator ivec1 = vec.begin();
int i1 = *ivec1;

int l = vec.capacity () * 2 + 1;
for (int i=0; i<l; i++)
vec.push_back (i+1);

vector<int>::const_iterator ivec=vec.begin(), e=vec.end();
for (; ivec != e; ++ivec)
if ((ivec1 == ivec) && (i1 = *ivec))
{
cout << "OK! The old iterator of vector is in effect!" << endl;
break;
}
if (ivec == e)
{
cout << "The old iterator of vector is nullity!" << endl;
}

system ("Pause");
return 0;
}
...全文
115 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
fingster 2003-06-11
  • 打赏
  • 举报
回复
楼上说的没错。
当vector内存重新分配的时候iterator就失效。
短歌如风 2003-06-11
  • 打赏
  • 举报
回复
vector不保证在添加元素后原迭代器的有效性,如果你需要这种保证,使用list。deque的保证比vector强一些。
或者另写一个具有安全一些的迭代器的vector,迭代器不保存指针,而是保存vector的引用和索引号,把用指针访问改为用vector::operator[]去访问,不过效率上会有影响。
boxban 2003-06-11
  • 打赏
  • 举报
回复
The semantics of iterator invalidation for deque is as follows. Insert (including push_front and push_back) invalidates all iterators that refer to a deque. Erase in the middle of a deque invalidates all iterators that refer to the deque. Erase at the beginning or end of a deque (including pop_front and
pop_back) invalidates an iterator only if it points to the erased element.


A vector's iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting an element in the middle of a vector invalidates all iterators that point to elements following the insertion or deletion point. It follows that you can prevent a vector's iterators from being invalidated if you use reserve() to preallocate as much memory as the vector will ever use, and if all insertions and deletions are at the vector's end.

A list is a doubly linked list. That is, it is a Sequence that supports both forward and backward traversal, and (amortized) constant time insertion and removal of elements at the beginning or the end, or in the middle. Lists have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed. The ordering of iterators may be changed (that is, list<T>::iterator might have a different predecessor or successor after a list operation than it did before), but the iterators themselves will not be invalidated or made to point to different elements unless that invalidation or mutation is explicit.

A slist is a singly linked list: a list where each element is linked to the next element, but not to the previous element. That is, it is a Sequence that supports forward but not backward traversal, and (amortized) constant time insertion and removal of elements. Slists, like lists, have the important property that insertion and splicing do not invalidate iterators to list elements, and that even removal invalidates only the iterators that point to the elements that are removed. The ordering of iterators may be changed (that is, slist<T>::iterator might have a different predecessor or successor after a list operation than it did before), but the iterators themselves will not be invalidated or made to point to different elements unless that invalidation or mutation is explicit.


A bit_vector's iterators are invalidated when its memory is reallocated. Additionally, inserting or deleting a bit in the middle of a bit_vector invalidates all iterators that point to bits following the insertion or deletion point. It follows that you can prevent a bit_vector's iterators from being invalidated if you use reserve() to preallocate as much storage as the bit_vector will ever use, and if all insertions and deletions are at the bit_vector's end.

Set/multiset/hash_set/hash_multiset has the important property that inserting a new element into a set does not invalidate iterators that point to existing elements. Erasing an element from a set also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.

Map/multimap/hash_map/hash_multimap has the important property that inserting a new element into a map does not invalidate iterators that point to existing elements. Erasing an element from a map also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.


A stack is an adaptor that provides a restricted subset of Container functionality: it provides insertion, removal, and inspection of the element at the top of the stack. Stack is a "last in first out" (LIFO) data structure: the element at the top of a stack is the one that was most recently added. Stack does not allow iteration through its elements.
Stack is a container adaptor, meaning that it is implemented on top of some underlying container type.By default that underlying type is deque, but a different type may be selected explicitly.


A queue is an adaptor that provides a restricted subset of Container functionality. A queue is a "first in first out" (FIFO) data structure. That is, elements are added to the back of the queue and may be removed from the front; Q.front() is the element that was added to the queue least recently. Queue does not allow iteration through its elements.
Queue is a container adaptor, meaning that it is implemented on top of some underlying container type. By default that underlying type is deque, but a different type may be selected explicitly.

A priority_queue is an adaptor that provides a restricted subset of Container functionality: it provides insertion of elements, and inspection and removal of the top element. It is guaranteed that the top element is the largest element in the priority_queue, where the function object Compare is used for comparisons. Priority_queue does not allow iteration through its elements.
Priority_queue is a container adaptor, meaning that it is implemented on top of some underlying container type. By default that underlying type is vector, but a different type may be selected explicitly.

cxjddd 2003-06-11
  • 打赏
  • 举报
回复
我也是认为当需要从新分配内存的时候,以前的iterator会失效。所以,最好用reserve来预定大小,这样就可以确定在某个范围里不会让iterator失效了。
chinazcw 2003-06-11
  • 打赏
  • 举报
回复
是失效了,学艺为精,说不出为什么?
GaoYakun 2003-06-11
  • 打赏
  • 举报
回复
最好的办法是读stl源码和stl标准。
fangrk 2003-06-11
  • 打赏
  • 举报
回复
当size()==capacity()并且添加元素的时候,iterator失效
cxjddd 2003-06-11
  • 打赏
  • 举报
回复
汗!出错了!程序中第一个if应该是i1 == *ivec。
幸好对vector没有什么关系。请大家注意了。
内容概要:本文详细介绍了一个基于C++语言开发的疫苗接种和儿童体检系统的设计与实现全过程,涵盖项目背景、目标意义、架构设计、核心功能模块、数据库实现、API接口规范、前后端代码实现及部署应用等多个方面。系统采用分层架构与模块化设计,实现了儿童信息管理、疫苗接种记录、体检数据录入、多用户权限控制、数据统计分析、异常预警、安全加密与日志审计等核心功能,并通过MySQL数据库进行数据持久化,结合Qt实现图形化界面,支持高并发、数据脱敏、多平台对接与自动化部署。项目强调数据安全、隐私保护与系统可扩展性,适用于社区医疗、疾控中心、学校及医院等场景。; 适合人群:具备C++编程基础,熟悉数据库操作和基本软件工程流程的开发人员、计算机及相关专业学生、医疗信息化项目开发者,以及希望了解完整医疗管理系统开发流程的技术人员。; 使用场景及目标:①学习如何使用C++构建完整的医疗信息管理系统;②掌握数据库设计、前后端交互、权限控制、多线程处理和GUI开发等关键技术;③应用于社区卫生服务、学校健康管理、疾控数据统计等实际业务场景,提升儿童健康管理水平;④作为课程设计、毕业设计或实际项目的参考模板。; 阅读建议:建议读者结合文档中的代码示例与数据库脚本,搭建本地开发环境进行实践操作,重点关注系统架构设计、模块解耦、安全机制与前后端交互逻辑,深入理解各功能模块的实现原理,并尝试在此基础上进行功能扩展,如接入移动端或增加AI分析模块。

24,857

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧