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)!