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

时间:2020-06-03 02:22:54

标签: c++ vector iterator dereference

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 ++中的向量和迭代器。在上面的代码中,为什么“ line abc”打印为0。它不应该打印99吗?当我使用for循环打印所有矢量元素时,也会打印99,但是为什么abc行不这样做?我取消引用迭代器* it,并希望它保留元素99。

2 个答案:

答案 0 :(得分:1)

插入向量时,所有先前的迭代器均无效。 veclist.insert(it,20)之后的所有内容都是未定义的行为。

要更准确地了解引擎盖下发生的情况,第一个打印有效而第二个无效的原因是由于分配的std::vector容量。大多数实现只分配 2 ^ N个内存块。

因此,初始向量的容量为4。将大小从3增加到4时,所有先前的迭代器都将保持有效。但是,当大小从4增加到8时,内存将被复制到新区域中,因此您正在访问已删除的内存。

要解决此问题,您可以简单地使用std::vector::insert的结果,作为有效迭代器指向插入的元素:

例如

it = veclist.insert(it,20);

答案 1 :(得分:1)

因为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
相关问题