C++ 面试题 目录

C++ 中什么是迭代器失效 (iterator invalidation)?

推荐答案

在C++中,迭代器失效指的是当容器发生某些操作(如插入、删除、扩容等)时,原先指向容器元素的迭代器可能不再有效。继续使用这些失效的迭代器会导致未定义行为(Undefined Behavior),如程序崩溃或数据损坏。

本题详细解读

1. 什么是迭代器失效?

迭代器失效是指当容器内部结构发生变化时,原先指向容器元素的迭代器可能不再指向有效的元素或内存位置。这种情况下,继续使用这些迭代器会导致未定义行为。

2. 常见的迭代器失效场景

以下是几种常见的导致迭代器失效的场景:

2.1 向std::vector插入或删除元素

  • 插入元素:当向std::vector插入元素时,如果插入操作导致容器重新分配内存(如容量不足时),所有指向该容器的迭代器都会失效。
  • 删除元素:删除std::vector中的元素时,被删除元素及其后面的所有元素的迭代器都会失效。

2.2 向std::deque插入或删除元素

  • 插入元素:在std::deque的中间插入元素时,所有迭代器都会失效;在两端插入元素时,只有指向插入位置的迭代器会失效。
  • 删除元素:删除std::deque中的元素时,被删除元素及其相邻元素的迭代器会失效。

2.3 向std::list插入或删除元素

  • 插入元素:在std::list中插入元素不会使任何迭代器失效。
  • 删除元素:删除std::list中的元素时,只有指向被删除元素的迭代器会失效。

2.4 向std::mapstd::set插入或删除元素

  • 插入元素:在std::mapstd::set中插入元素不会使任何迭代器失效。
  • 删除元素:删除std::mapstd::set中的元素时,只有指向被删除元素的迭代器会失效。

3. 如何避免迭代器失效?

  • 谨慎操作:在对容器进行插入或删除操作时,注意检查迭代器的有效性。
  • 使用返回值:某些容器操作(如erase)会返回一个有效的迭代器,指向被删除元素的下一个元素,可以使用这个返回值来更新迭代器。
  • 避免在循环中直接删除:在遍历容器时,如果需要删除元素,建议使用erase的返回值来更新迭代器,或者使用std::remove_if等算法。

4. 示例代码

-- -------------------- ---- -------
-------- --------
-------- ----------

--- ------ -
    ---------------- --- - --- -- -- -- ---
    ---- -- - ----------- - --  -- -----

    ---------------------- - -- ----  -- ------
    -- ------------------------

    --------- -- --- -- ----------  -- -----
    ------ --
-

在这个例子中,插入操作可能导致it失效,继续使用it会导致未定义行为。

纠错
反馈