list迭代器失效场景及应对策略
- erase操作:
- 失效场景:当对list使用erase删除一个元素时,指向被删除元素的迭代器会失效,而erase函数会返回下一个有效的迭代器。
- 应对策略:使用erase返回的迭代器来继续遍历,例如:
std::list<int> myList = {1, 2, 3, 4, 5};
auto it = myList.begin();
while (it != myList.end()) {
if (*it == 3) {
it = myList.erase(it);
} else {
++it;
}
}
- clear操作:
- 失效场景:调用list的clear函数会删除list中的所有元素,所有迭代器都会失效。
- 应对策略:在调用clear后,不要再使用之前的迭代器,若需要重新遍历,应重新获取begin和end迭代器,例如:
std::list<int> myList = {1, 2, 3, 4, 5};
auto it = myList.begin();
myList.clear();
// 这里it已失效,重新获取迭代器
it = myList.begin();
vector迭代器失效场景及应对策略
- 插入操作(insert):
- 失效场景:
- 在vector的头部或中间插入元素时,由于vector可能需要重新分配内存空间(当容量不足时),所有迭代器都会失效。
- 在vector尾部插入元素,当当前容量小于新元素个数(导致重新分配内存)时,所有迭代器失效;若未重新分配内存,指向插入位置之后的迭代器会失效。
- 应对策略:插入操作后重新获取迭代器。例如在头部插入元素:
std::vector<int> myVector = {1, 2, 3, 4, 5};
auto it = myVector.begin();
myVector.insert(it, 0);
// it已失效,重新获取迭代器
it = myVector.begin();
- 删除操作(erase):
- 失效场景:删除元素后,指向被删除元素及之后的迭代器都会失效。
- 应对策略:使用erase返回的迭代器继续遍历,例如:
std::vector<int> myVector = {1, 2, 3, 4, 5};
auto it = myVector.begin();
while (it != myVector.end()) {
if (*it == 3) {
it = myVector.erase(it);
} else {
++it;
}
}
- resize操作:
- 失效场景:如果resize后的大小大于当前容量,会重新分配内存,所有迭代器失效;如果resize后的大小小于当前容量,指向原vector超出新大小部分的迭代器会失效。
- 应对策略:resize操作后重新获取迭代器。例如:
std::vector<int> myVector = {1, 2, 3, 4, 5};
auto it = myVector.begin();
myVector.resize(3);
// it可能已失效,重新获取迭代器
it = myVector.begin();
- clear操作:
- 失效场景:调用vector的clear函数会删除所有元素,所有迭代器都会失效。
- 应对策略:和list类似,clear后重新获取迭代器,例如:
std::vector<int> myVector = {1, 2, 3, 4, 5};
auto it = myVector.begin();
myVector.clear();
// it已失效,重新获取迭代器
it = myVector.begin();