C ++: vector iterator invalidation when deleting elements


1. Delete the last element

#include <iostream>
#include <vector>
using namespace std;
//输出
void show(vector<int> &v);
//迭代器
vector<int>::iterator i1, i2, i3, i4;

int main()
{
    vector<int> vi{1, 2, 3};
    //迭代器
    i1 = vi.begin();
    i2 = vi.begin() + 1;
    i3 = vi.begin() + 2;
    i4 = vi.end();
    //输出
    show(vi);
    //在末尾删除
    vi.pop_back();
    //输出
    show(vi);
    return 0;
}

void show(vector<int> &v)
{
    cout << "vector:   ";
    for (auto &a : v)
    {
        cout << a << "(" << &a << ")"
             << "\t";
    }

    cout << "\ni1~i4:    ";
    for (auto a = i1; a != i4; ++a)
    {
        cout << *a << "\t\t";
    }

    cout << "\niterate:  ";
    cout << *i1 << "(" << &(*i1) << ")"
         << "\t";
    cout << *i2 << "(" << &(*i2) << ")"
         << "\t";
    cout << *i3 << "(" << &(*i3) << ")"
         << "\t";
    cout << *i4 << "(" << &(*i4) << ")"
         << "\t"; //解引用尾后迭代器未定义

    cout << endl
         << endl;
}

operation result

After dropping the elements of comparison

analysis:

  1. After deleting the last element, vector only two elements, but when traversing i1 i4 still read three elements, i3 and i4 description has expired.
  2. vi i3 point of the element before deleting the third element, the tail removing elements i3 point vi elements, also shows i3 has expired.
  3. i4 point before the tail element vi remove elements, after removing elements unknown point memory area i3, i4 also shows has lapsed.

2. Delete the middle element

#include <iostream>
#include <vector>
using namespace std;
//输出
void show(vector<int> &v);
//迭代器
vector<int>::iterator i1, i2, i3, i4;

int main()
{
     vector<int> vi{1, 2, 3};
     //迭代器
     i1 = vi.begin();
     i2 = vi.begin() + 1;
     i3 = vi.begin() + 2;
     i4 = vi.end();
     //输出
     show(vi);
     //删除第2个元素
     vi.erase(i2);
     //输出
     show(vi);
     return 0;
}

void show(vector<int> &v)
{
     cout << "vector:   ";
     for (auto &a : v)
     {
          cout << a << "(" << &a << ")"
               << "\t";
     }

     cout << "\ni1~i4:    ";
     for (auto a = i1; a != i4; ++a)
     {
          cout << *a << "\t\t";
     }

     cout << "\niterate:  ";
     cout << *i1 << "(" << &(*i1) << ")"
          << "\t";
     cout << *i2 << "(" << &(*i2) << ")"
          << "\t";
     cout << *i3 << "(" << &(*i3) << ")"
          << "\t";
     cout << *i4 << "(" << &(*i4) << ")" //解引用尾后迭代器未定义
          << "\t";
     cout << endl
          << endl;
}

operation result

After dropping the elements of comparison

analysis:

  1. After deleting the last element, vector only two elements, but when traversing i1 i4 still read three elements, i3 and i4 description has expired.
  2. After dropping the elements, * i2 from 2 becomes 3, indicating that i2 has expired.

3. Delete the first element

#include <iostream>
#include <vector>
using namespace std;
//输出
void show(vector<int> &v);
//迭代器
vector<int>::iterator i1, i2, i3, i4;

int main()
{
     vector<int> vi{1, 2, 3};
     //迭代器
     i1 = vi.begin();
     i2 = vi.begin() + 1;
     i3 = vi.begin() + 2;
     i4 = vi.end();
     //输出
     show(vi);
     //删除第1个元素
     vi.erase(i1);
     //输出
     show(vi);

     return 0;[图片上传中...(捕获.PNG-c60d0f-1585299439619-0)]

}

void show(vector<int> &v)
{
     cout << "vector:   ";
     for (auto &a : v)
     {
          cout << a << "(" << &a << ")"
               << "\t";
     }

     cout << "\ni1~i4:    ";
     for (auto a = i1; a != i4; ++a)
     {
          cout << *a << "\t\t";
     }

     cout << "\niterate:  ";
     cout << *i1 << "(" << &(*i1) << ")"
          << "\t";
     cout << *i2 << "(" << &(*i2) << ")"
          << "\t";
     cout << *i3 << "(" << &(*i3) << ")"
          << "\t";
     cout << *i4 << "(" << &(*i4) << ")" //解引用尾后迭代器未定义
          << "\t";
     cout << endl
          << endl;
}

operation result

After dropping the elements of comparison

analysis:

  1. After deleting the last element, vector only two elements, but when traversing i1 i4 still read three elements, i3 and i4 description has expired.
  2. After dropping the elements, * i2 from 2 becomes 3, indicating that i2 has expired.
  3. After dropping the elements, * i1 from a 1 to 2, indicating that i1 has expired.

4. Summary

  1. Delete elements in the vector, if the element before the iterator points to remove elements, the iterator still valid. If the iterator to the element and the element is deleted later, the iterator will fail.
  2. When adding, deleting, modifying elements, as far as possible directly begin () and End (), or use the insert () and erase () to update the corresponding iterator, avoiding intermediate amount iterator.
vector<int> vi;
//i保存的是vi的迭代器,有时操作后(如添加元素,删除元素)不确定i是否有效
auto i=vi.begin()+n;
vi.erase(i);
//尽量直接使用begin()和end(),避免使用中间量i
vi.erase(vi.begin()+n);
//下面的表达式更好,因为它会自动更新i
i=vi.erase(i);
Published 77 original articles · won praise 25 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_34801642/article/details/105155302