MST

星途 面试题库

面试题:C++ STL迭代器begin失效后的行为及预防

假设在使用std::vector<int>时,由于某种操作导致begin迭代器失效,此时若继续使用失效的begin迭代器进行遍历,程序会出现什么行为?如何在代码设计中有效预防这种因begin迭代器失效而引发的问题?请结合代码示例说明。
10.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

程序行为

std::vector<int>begin 迭代器失效后继续使用它进行遍历,程序会出现未定义行为。这可能导致程序崩溃、产生错误的结果或者出现其他难以预测的情况。原因在于 std::vector 在某些操作(如插入或删除元素,且导致重新分配内存时),其内部存储的位置可能会改变,迭代器指向的原内存位置可能已无效。

预防措施及代码示例

  1. 重新获取迭代器:在可能导致迭代器失效的操作后,重新获取 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;
}
  1. 使用 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;
}
  1. 了解容器操作对迭代器的影响:在进行可能改变容器大小或结构的操作前,先查阅文档了解该操作对迭代器的影响,尽量避免在遍历过程中进行可能导致迭代器失效的操作。如果必须进行,做好重新获取迭代器的准备。