迭代器如何在向量重新分配后更新
How do iterators update after vector reallocation
下面是我正在查看的代码片段:
vector<int> iv = {1,2,3,4,5,6,7,8,9,10};
auto iter = iv.begin(), mid = iv.begin() + iv.size()/2;
for(int count = 100; count; --count ) {
iter = iv.insert(iter, - 1);
cout << "capacity = " << iv.capacity() << "*mid = " << *mid << endl;
}
根据迭代器无效规则:
vector:插入点之前的所有迭代器和引用都不受影响,除非新容器大小大于以前的容量(在这种情况下,所有迭代者和引用都无效)[23.2.4.3/1]迭代器无效规则
我知道,由于我在每次插入操作中都会重新分配"iter"的值,也许我能够保持它的有效性(如果我错了,请纠正我)。然而,在这种情况下,迭代器"mid"仍然有效,即使我没有在循环中篡改它,而且当向量的容量发生变化时也是如此。
那么,"mid"如何在重新分配后更新自身呢?
为了知道mid是否在更改,我将代码中的第4行更改为:
iv.insert(iter, -1); // Did not assign it back to iter.
在mid处打印取消引用值的结果表明发生了更改,也许iter也无效。(再次,如果我错了,请纠正我)。
您的理解是正确的。一旦容量增加,任何迭代器都将无效。即使容量没有改变,mid
迭代器也会变为无效,但它基本上指向前一个元素。
因此,原始代码至少对iter
有效,但mid
在第一次插入时将变得不可用。经过修改后,代码完全无效。
通常,vector
迭代器的实现只是一个简单的指针,指向某个元素以支持数组。因此,当容量发生变化并且数组被重新分配时,任何这样的迭代器都不再有效,因为指针指向不再有效的内存。结果,您可能会看到垃圾,可能会出现分段错误,或者随机看到正确的值。当容量不变时,数组中的元素可能会向前移动,这样您就可以在插入点之后看到迭代器中的前一个元素,但前提是数组开头没有空元素(例如start
大于零)。但所有这些都是特定于实现的,因此标准明确规定上述大部分都是未定义的行为。
相关文章:
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- vector.resize()中的分配错误
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- cmake更新缓存的变量
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 分配帮助更新特定城市中"shipments"和"orders"的每项项目的数量
- 迭代器如何在向量重新分配后更新
- C++分配后字符串大小未更新
- 如果通过指针分配,C++ vector.size() 不会更新
- 返回新分配的指针或通过参数更新对象