一、vector迭代器失效

vector是先行存储的,大部分时候的插入删除操作都有可能导致迭代器失效。失效场景:

  • 执行插入操作时,end指针失效,如果此时重新分配内存了,所有的迭代器失效,否则其他迭代器可能不会失效。
  • 执行删除操作时,所有的迭代器都会失效

示例代码:

vector<int> data;
vector<int>::iterator it;
data.push_back(100);
data.push_back(200);
data.push_back(300);
data.push_back(400);

for (it = data.begin(); it != data.end(); it++) {
    cout << *it << endl;
    if (*it == 300)
        data.erase(it); // 删除之后将会失效
}

二、list迭代器失效

失效规则:

  • 插入操作(insert)和接合操作(splice)不会造成原有的list迭代器失效
  • 删除操作(erase)只有指向被删除元素的那个迭代器失效,其他迭代器不受影响

list不是线性存储的,链式存储的好处就是方便增加和删除,不会影响原有的内存空间。

三、deque迭代器失效

失效规则:

  • 在deque容器首部或者尾部插入元素不会使得任何迭代器失效,vs环境下测试会失效,但是g++没有失效
  • 在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效
  • 在deque容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器失效
// 首尾添加元素,在vs环境下测试失效,g++正常
void deque_f() {
    deque<int> q;
    deque<int>::iterator it;

    q.push_back(100);
    q.push_back(200);
    q.push_back(300);
    q.push_back(400);

    for (it = q.begin(); it != q.end(); it++) {
        cout << *it << endl;
        if (*it == 200) // 不会失效
            q.push_front(50);
        if (*it == 300) // 不会失效,且最后会输出500
            q.push_back(500);
    }

}

四、map和set

map和set底层都是红黑树,不是线性存储,它们的失效规则:

  • 执行插入操作时,原有的迭代器不会失效
  • 删除操作时,其他的迭代器不会失效,被删除元素的迭代器失效
最后修改:2019 年 05 月 04 日
如果觉得我的文章对你有用,请随意赞赏