面试题答案
一键面试异常情况及举例
- 解引用异常:
- 当使用
end()
返回的迭代器进行解引用操作时会出错。因为end()
返回的迭代器指向容器最后一个元素的下一个位置,该位置没有实际元素。 - 例如:
- 当使用
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3};
auto it = vec.end();
// 以下操作会导致未定义行为,因为it指向的位置没有实际元素
std::cout << *it << std::endl;
return 0;
}
- 越界访问异常:
- 如果在
end()
之后继续移动迭代器并进行访问操作,也会引发问题。 - 例如:
- 如果在
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3};
auto it = vec.end();
// 这里试图将迭代器向后移动并访问,会导致越界访问
it++;
if (it != vec.end()) {
std::cout << *it << std::endl;
}
return 0;
}
处理方法
- 避免解引用
end()
返回的迭代器:- 在循环遍历容器时,确保循环条件正确,不要在
end()
处解引用。 - 例如,正确的遍历方式:
- 在循环遍历容器时,确保循环条件正确,不要在
#include <vector>
#include <iostream>
int main() {
std::vector<int> vec = {1, 2, 3};
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << std::endl;
}
return 0;
}
- 防止越界访问:
- 在移动迭代器时,要保证不超过
end()
。如果需要移动迭代器,可以使用advance
等标准库函数,并结合end()
进行边界检查。 - 例如:
- 在移动迭代器时,要保证不超过
#include <vector>
#include <iostream>
#include <iterator>
int main() {
std::vector<int> vec = {1, 2, 3};
auto it = vec.begin();
std::advance(it, 2); // 移动迭代器
if (it != vec.end()) {
std::cout << *it << std::endl;
}
return 0;
}
通过正确的迭代器使用和边界检查,可以有效避免使用end()
时可能出现的异常情况。