C ++: vector iterator invalidation when the insert elements



1. capacity () less than at the end add elements

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

int main()
{
    vector<int> vi{1, 2};
    i1 = vi.begin();
    i2 = ++vi.begin();
    i3 = vi.end();
    //输出
    show(vi);
    //在末尾插入
    vi.push_back(3);
    //输出
    show(vi);

    return 0;
}

void show(vector<int> &v)
{
    cout << "size:     " << v.size() << endl;
    cout << "capaticy: " << v.capacity() << endl;
    cout << "vector:   ";

    for (auto &a : v)
    {
        cout << a << "(" << &a << ")"
             << "\t";
    }
    cout << endl
         << "iterate:  ";

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

operation result
FIG insert elements before and after comparison
analysis:

  1. Because the size () == capacity (), so that the insert elements, vector memory is reallocated. vi originally from 0x3a0f88 start, insert elements, vi 0x3a0f98 from the start.
  2. Before inserting elements, i1 point vi first element, i2 vi point in the second element, i3 point to the end of the element does not exist, * i3 is undefined.
  3. After insertion elements, vector memory is reallocated, i1, i2 and i3 unknown point memory area, so i1, i2 and i3 has expired.

2. capacity () sufficient to add elements to the end

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

int main()
{
     vector<int> vi{1, 2};
     //扩充存储空间
     vi.reserve(4);
     //迭代器
     i1 = vi.begin();
     i2 = ++vi.begin();
     i3 = vi.end();
     //输出
     show(vi);
     //在末尾插入
     vi.push_back(3);
     //输出
     show(vi);

     return 0;
}

void show(vector<int> &v)
{
     cout << "size:     " << v.size() << endl;
     cout << "capaticy: " << v.capacity() << endl;
     cout << "vector:   ";

     for (auto &a : v)
     {
          cout << a << "(" << &a << ")"
               << "\t";
     }
     cout << endl
          << "iterate:  ";

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

operation result

FIG insert elements before and after comparison

analysis:

  1. Because the size () <capacity (), so that the insert elements, vector memory address unchanged.
  2. Before and after insertion elements, i1 always points to the first element vi, i2 vi always point in the first two elements, and its value has not changed. Therefore, i1 and i2 are still valid.
  3. Before inserting elements, i3 point after the last element vi absence, * i3 is undefined; the insert elements, * i3 = 3, after the last element no longer points, it i3 failure.

3. capacity () sufficient additive element in the intermediate

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

int main()
{
    vector<int> vi{1, 2};
    //扩充存储空间
    vi.reserve(4);
    //迭代器
    i1 = vi.begin();
    i2 = ++vi.begin();
    i3 = vi.end();
    //输出
    show(vi);
    //在第2个元素之前插入
    vi.insert(i2, 3);
    //输出
    show(vi);

    return 0;
}

void show(vector<int> &v)
{
    cout << "size:     " << v.size() << endl;
    cout << "capaticy: " << v.capacity() << endl;
    cout << "vector:   ";

    for (auto &a : v)
    {
        cout << a << "(" << &a << ")"
             << "\t";
    }
    cout << endl
         << "iterate:  ";

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

operation result

FIG insert elements before and after comparison

analysis:

  1. Because the size () <capacity (), so that the insert elements, vector memory address unchanged.
  2. Before and after insertion elements, i1 always points to the first element of vi, and its value has not changed. Therefore, i1 is still valid.
  3. Before inserting elements, i2 point vi second element, * i2 = 2; after insertion elements, i2 vi still points of two elements, but * i2 = 3, so that i2 has expired.
  4. Before inserting elements, i3 point after the last element vi absence, * i3 is undefined; the insert elements, * i3 = 2, no tail pointing element, it i3 failure.

4. capacity () sufficient of additive elements in the first portion

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

int main()
{
     vector<int> vi{1, 2};
     //扩充存储空间
     vi.reserve(4);
     //迭代器
     i1 = vi.begin();
     i2 = ++vi.begin();
     i3 = vi.end();
     //输出
     show(vi);
     //在第1个元素之前插入
     vi.insert(i1, 3);
     //输出
     show(vi);

     return 0;
}

void show(vector<int> &v)
{
     cout << "size:     " << v.size() << endl;
     cout << "capaticy: " << v.capacity() << endl;
     cout << "vector:   ";

     for (auto &a : v)
     {
          cout << a << "(" << &a << ")"
               << "\t";
     }
     cout << endl
          << "iterate:  ";

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

operation result

FIG insert elements before and after comparison

analysis:

  1. Because the size () <capacity (), so that the insert elements, vector memory address unchanged.
  2. Before and after insertion elements, i1 always points to the first element of vi, but * i1 from a 1 to 3. Therefore, i1 failure.
  3. Before and after insertion elements, i2 vi always points of two elements, but from the 2 * i2 becomes 1. Therefore, i2 failure.
  4. Before inserting elements, i3 point after the last element vi absence, * i3 is undefined; the insert elements, * i3 = 2, no tail pointing element, it i3 failure.

5. Summary

1. When the size () == capacity (), the insertion element in the vector memory is reallocated, pointing element iterator will fail.
2. When the size () <capacity (), vector memory will not be reallocated when the insert elements. At this time, if the iterator to the element before the insertion position, it is still valid; if the iterator to the element after the insertion position, it will be deactivated.

Published 77 original articles · won praise 25 · views 10000 +

Guess you like

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