自学内容网 自学内容网

C/C++|STL迭代器失效场景总结

std::vector 和 std::string

插入元素:当插入元素时,如果 vector 和 string 需要扩容,则所有迭代器失效
删除元素:删除元素时,删除点及其之后的所有迭代器失效

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main() {
    // 1. std::vector 的迭代器失效示例
    vector<int> v = {1, 2, 3, 4, 5};
    auto it = v.begin() + 2;  // 指向 3

    // 插入元素导致扩容,所有迭代器失效
    v.push_back(6);  // 可能导致重新分配内存
    cout << *it << endl;  // 未定义行为,迭代器失效

    // 2. std::string 的迭代器失效示例
    string s = "hello";
    auto sit = s.begin() + 1;  // 指向 'e'

    // 插入字符可能导致扩容
    s.push_back('!');
    cout << *sit << endl;  // 未定义行为,迭代器失效

    return 0;
}

std::deque

插入元素:他由于控制了层次级的数组块,所以两端插入元素,所有迭代器和引用都保持有效。但是如果在中间插入元素(此时变成了和 std::vector 一样的情况),插入点及其之后的迭代器都会失效。
删除元素:同理,两段删除元素,迭代器保持有效;删除中间元素时,删除点及其之后的迭代器失效。

#include <iostream>
#include <deque>
using namespace std;

int main() {
    deque<int> d = {1, 2, 3, 4, 5};
    auto it = d.begin() + 2;  // 指向 3

    // 在中间插入元素,迭代器失效
    d.insert(d.begin() + 2, 10);
    cout << "After insertion, the iterator is: " << *it << endl;  // 未定义行为,迭代器失效

    return 0;
}

std::list 和 std::forward_list

插入元素:在 std::list 和 std::forward_list 中插入元素时,不会导致其他迭代器失效。(因为他在内存中并不是顺序排列的)
删除元素:仅指向被删除元素的迭代器失效,其他迭代器保持有效。

#include <iostream>
#include <list>
#include <forward_list>
using namespace std;

int main() {
    // std::list 的迭代器失效示例
    list<int> lst = {1, 2, 3, 4, 5};
    auto it = lst.begin();
    advance(it, 2);  // 指向 3

    // 删除元素 3,指向 3 的迭代器失效
    lst.erase(it);
    // cout << *it << endl;  // 迭代器失效,不能再使用

    // std::forward_list 的迭代器失效示例
    forward_list<int> flst = {1, 2, 3, 4, 5};
    auto fl_it = flst.begin();
    advance(fl_it, 2);  // 指向 3

    // 删除元素 3,指向 3 的迭代器失效
    flst.remove(3);
    // cout << *fl_it << endl;  // 迭代器失效,不能再使用

    return 0;
}

std::set/std::map

插入元素:底层是红黑树,无论如何插入元素都不会导致其他迭代器失效。(红黑树也是一种链式结构,并不是统一的数据块,所以不会导致失效)
删除元素:删除元素时,仅指向被删除元素的迭代器失效。

#include <iostream>
#include <set>
#include <map>
using namespace std;

int main() {
    // std::set 的迭代器失效示例
    set<int> s = {1, 2, 3, 4, 5};
    auto it = s.find(3);

    // 删除元素 3,指向 3 的迭代器失效
    s.erase(it);
    // cout << *it << endl;  // 迭代器失效,不能再使用

    // std::map 的迭代器失效示例
    map<int, string> m = {{1, "one"}, {2, "two"}, {3, "three"}};
    auto mit = m.find(3);

    // 删除元素 3,指向 3 的迭代器失效
    m.erase(mit);
    // cout << mit->second << endl;  // 迭代器失效,不能再使用

    return 0;
}

std::unordered_map / std::unordered_set

插入元素:插入元素不会导致其他迭代器失效,除非容器进行扩容(即哈希表重新分配内存),此时会导致所有迭代器都失效
删除元素:删除元素时,仅指向被删除元素的迭代器失效

#include <iostream>
#include <unordered_map>
#include <unordered_set>
using namespace std;

int main() {
    // std::unordered_map 的迭代器失效示例
    unordered_map<int, string> umap = {{1, "one"}, {2, "two"}, {3, "three"}};
    auto it = umap.find(2);

    // 插入新元素,可能导致哈希表扩容,迭代器失效
    umap.insert({4, "four"});
    cout << it->second << endl;  // 可能导致迭代器失效

    return 0;
}

std::array

std::array 的行为和普通数组非常类似,不能进行插入和删除操作,所以迭代器不会失效


原文地址:https://blog.csdn.net/caiziming_001/article/details/142325066

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!