C++ 使用向量迭代器时出错';插入和擦除后

C++ 使用向量迭代器时出错';插入和擦除后,c++,C++,我试图在C++中使用向量。我试图使用迭代器在指定位置插入一个元素,然后再次使用迭代器删除一些元素。但是,当对这两个操作使用相同的迭代器时,我得到了错误。下面是我的代码- #include <iostream> #include <vector> #include <cctype> using namespace std; int main() { vector <int> A(10); for (int i=0;i<A.si

我试图在
C++
中使用向量。我试图使用迭代器在指定位置插入一个元素,然后再次使用迭代器删除一些元素。但是,当对这两个操作使用相同的迭代器时,我得到了错误。下面是我的代码-

#include <iostream>
#include <vector>
#include <cctype>
using namespace std;
int main()
{
    vector <int> A(10);

    for (int i=0;i<A.size();i++)
    {
        A[i]=i+1;
    }
    vector<int>::iterator p=A.begin();
    p+=2;

    A.insert(p,1,55);

    A.erase(p,p+2);
    for (int i=0;i<A.size();i++)
    {
        cout << A[i] <<"\n";
    }   
    return 0;
}
如果我在A.erase前面加上以下两行,我会得到正确的答案

p=A.begin();
p+=2;
A.erase(p,p+2);

因此,如果p仍然指向同一个元素,因为它的值尚未更改,为什么我需要再次设置p的值。

在插入/删除
std::vector
后,所有现有迭代器都无效,不应使用(使用它们将导致未定义的行为)

请记住,更改向量包含的项可能会导致内存分配等,所以旧的迭代器可以指向释放的内存(如指针)

所以,当您添加您提到的行并重新初始化迭代器时,一切都正常。但是在
insert
之后,现有的
p
不再有效

检查:和中有关“迭代器无效”的段落


您可以考虑添加调用<代码> Reave<代码>,以确保在<代码> INSERT <代码>上不发生再分配,但在我看来,这样的代码仍然容易出错,而且难以维护。

< P>从<代码> STD::vector < /代码>插入/删除>所有现有迭代器无效,不应使用。(使用它们将导致未定义的行为)

请记住,更改向量包含的项可能会导致内存分配等,所以旧的迭代器可以指向释放的内存(如指针)

因此,当您添加您提到的行并重新初始化迭代器时,一切都正常。但是在
insert
existing之后
p
不再有效

检查:和中有关“迭代器无效”的段落

您可以考虑添加调用<代码> Reals以确保在代码>插入INS/CODE >上没有再分配发生,但在我看来,这样的代码仍然容易出错,而且难以维护。

< P>根据标准(N429 6C++ 14)[23.3.6/5/1 ]插入向量无效迭代器的操作-但并不总是:

备注:如果新容量大于旧容量,则会导致重新分配。如果没有重新分配, 插入点之前的所有迭代器和引用都保持有效

和用于擦除[23.3.6.5/3]

效果:在擦除点或之后使迭代器和引用无效

这些是规则,您认为正确的行为实际上是UB(未定义的行为)-这意味着即使在99%的时间内,它看起来也可以工作。这还取决于编译器中的实现。

根据标准(n4296 C++14)[23.3.6.5/1]向量插入操作会使迭代器无效-但并不总是:

备注:如果新容量大于旧容量,则会导致重新分配。如果没有重新分配, 插入点之前的所有迭代器和引用都保持有效

和用于擦除[23.3.6.5/3]

效果:在擦除点或之后使迭代器和引用无效


这些是规则,您认为正确的行为实际上是UB(未定义的行为)-这意味着即使在99%的时间内,它看起来也可以工作。这也取决于编译器中的实现。

但是当我先使用
擦除
,然后使用
插入
时,它工作得很好。例如-
向量::迭代器p=A.begin();p+=2;A.erase(p,p+2);A.insert(p,1,3);
这很好。是的,因为向量实现可能不会在擦除时释放内存(insert有时必须分配内存)。但仍然-这是实现细节,您不应该依赖它。每当您执行更改向量大小的操作时,所有迭代器都应被视为“坏”。使迭代器无效只意味着使用它是未定义的行为—它有时可能会工作,有时会崩溃。此外,仅从向量中删除迭代器会使其无效日期迭代器指向已删除的元素或位于已删除的元素之后。指向已删除元素之前的迭代器仍然有效。但是,当我先使用
erase
,然后使用
insert
时,效果很好。例如-
vector::迭代器p=A.begin();p+=2;A.erase(p,p+2);A.insert(p,1,3);
这很好。是的,因为向量实现可能不会在擦除时释放内存(insert有时必须分配内存)。但仍然-这是实现细节,您不应该依赖它。每当您执行更改向量大小的操作时,所有迭代器都应被视为“坏”。使迭代器无效只意味着使用它是未定义的行为—它有时可能会工作,有时会崩溃。此外,仅从向量中删除迭代器会使其无效日期迭代器指向或位于已擦除元素之后。指向已擦除元素之前的迭代器仍然有效。
p=A.begin();
p+=2;
A.erase(p,p+2);