面试题答案
一键面试程序行为
当 std::vector<int>
的 begin
迭代器失效后继续使用它进行遍历,程序会出现未定义行为。这可能导致程序崩溃、产生错误的结果或者出现其他难以预测的情况。原因在于 std::vector
在某些操作(如插入或删除元素,且导致重新分配内存时),其内部存储的位置可能会改变,迭代器指向的原内存位置可能已无效。
预防措施及代码示例
- 重新获取迭代器:在可能导致迭代器失效的操作后,重新获取
begin
迭代器。
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin();
// 假设这里进行了可能导致迭代器失效的操作,如插入元素
vec.insert(vec.begin() + 2, 99);
// 重新获取begin迭代器
it = vec.begin();
for (; it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
- 使用
auto
类型推导:在遍历std::vector
时使用auto
来推导迭代器类型,这样在迭代器失效重新获取后,代码不需要额外修改。
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用auto推导迭代器类型
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 插入元素可能导致迭代器失效
vec.insert(vec.begin() + 2, 99);
// 重新遍历,重新获取迭代器(这里重新定义it,得益于auto推导)
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
- 了解容器操作对迭代器的影响:在进行可能改变容器大小或结构的操作前,先查阅文档了解该操作对迭代器的影响,尽量避免在遍历过程中进行可能导致迭代器失效的操作。如果必须进行,做好重新获取迭代器的准备。