首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ vector 迭代器失效:erase 後必須更新迭代器

     編輯:程式設計綜合問答

錯誤程式碼

vector vec = {0,1,1,2,3,5,8,13,21,55,89};
auto it = vec.begin();
while (it != vec.end()) {
    if (*it % 2) 
        vec.erase(it); // 錯誤:erase 使 it 失效
    else
        ++it;
}

崩潰原因

`vector::erase` 會將後續元素前移,**導致原迭代器 `it` 失效**(指向已被移動/銷毀的記憶體)。後續 `++it` 或比較 `it != vec.end()` 即為未定義行為,MSVC Debug 模式下拋出 `vector iterator incompatible`。

修正:使用 erase 返回值

`erase` 返回**指向被刪除元素下一個位置的有效迭代器**。

while (it != vec.end()) {
    if (*it % 2) 
        it = vec.erase(it); // 關鍵:接收返回值更新 it
    else
        ++it;
}

通用規則:STL 容器迭代器失效

操作vectordequelist/forward_listmap/set
`erase`**失效**(被刪除及之後)**失效**(被刪除及之後)**僅被刪除者失效****僅被刪除者失效**
`insert`/`push_back`**可能失效**(重新配置時)**失效****不失效****不失效**
返回值可用`erase`、`insert``erase`、`insert``erase`、`insert`、`splice``insert`、`erase`

現代 C++ 寫法:erase-if 慣用語 (C++20)

#include 
std::erase_if(vec, [](int x){ return x % 2 != 0; }); // 直接移除所有奇數

C++11~C++17 替代方案

// remove-erase 慣用語
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x){ return x % 2 != 0; }), vec.end());

結論

凡操作 `vector`/`deque`/`string` 等連續容器涉及插入刪除,**必須**使用返回值更新迭代器,或改用演算法 (`remove_if` + `erase` / `erase_if`)。養成查閱容器迭代器失效規則的習慣。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved