C++ 向量插入和迭代器混淆


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已经无效。像*itit++一样使用它会导致 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

最新更新