int main(){
vector<int> veclist;
veclist.push_back(90);
veclist.push_back(80);
veclist.push_back(70);
vector<int>::iterator it;
it=veclist.begin();
veclist.insert(it,20);
cout << *it << endl; // prints 20
it++;
veclist.insert(it,99);
cout << *it <<endl; // line abc : prints 0
}
嗨,我正在C++中使用向量和迭代器。在上面的代码中,为什么"行abc"打印为0。不应该打印99吗?当我使用 for 循环打印所有矢量元素时,也会打印 99,但为什么行 abc 不这样做?我正在取消引用迭代器 *it,我希望它包含元素 99。
插入向量时,所有以前的迭代器都将失效。veclist.insert(it,20)
之后的一切都是未定义的行为。
为了更准确地说,第一次打印有效而第二次打印无效的原因是因为分配了std::vector
容量。大多数实现只分配2^N 个内存块。
因此,初始向量的容量为 4。当您将大小从 3 增加到 4 时,所有以前的迭代器恰好保持有效。但是,当大小从 4 增加到 8 时,内存将复制到新区域中,因此您正在访问已删除的内存。
要解决此问题,您可以简单地使用std::vector::insert
的结果作为指向插入元素的有效迭代器:
例如
it = veclist.insert(it,20);
因为std::vector<T,Allocator>::insert
会导致迭代器失效。
如果新
size()
大于旧capacity()
,则会导致重新分配。如果新size()
大于capacity()
,则所有迭代器和引用都将失效。否则,只有插入点之前的迭代器和引用仍然有效。过去结束迭代器也失效。
这意味着在insert
的调用之后,it
已经无效。像*it
或it++
一样使用它会导致 UB。
你应该将it
分配给返回值insert
,这是指向插入值的迭代器。
vector<int>::iterator it;
it=veclist.begin();
it=veclist.insert(it,20);
cout << *it << endl; // prints 20
it++;
it=veclist.insert(it,99);
cout << *it <<endl; // prints 99