成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++中vector迭代器哪些情況下會失效?

開發 前端
為了避免由于迭代器失效引起的錯誤,我們在使用迭代器遍歷vector時,要避免在可能使迭代器失效的操作前后更新迭代器,或者盡量減少對vector的修改操作直到遍歷完成。

在C++編程中,std::vector是一個非常強大的容器,用于存儲動態數組。然而,使用std::vector時需要注意的一個重要方面是其迭代器的行為。當vector的容量發生變化時(例如添加或刪除元素),迭代器可能會失效,這可能導致程序錯誤。

迭代器失效的情況:

1、重新分配內存

當向vector添加新元素導致其容量不足時,vector會自動擴展以容納更多的元素。這種情況下,所有指向舊內存區域的迭代器、指針和引用都會失效。

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec = {1, 2, 3};
    auto it = vec.begin(); // 指向第一個元素


    // 添加一個元素可能觸發重新分配
    vec.push_back(4);


    if (it != vec.end()) {
        std::cout << "Element: " << *it << std::endl;
    } else {
        std::cout << "Iterator is invalid." << std::endl;
    }


    return 0;
}

在這個例子中,如果push_back()操作觸發了重新分配,則it迭代器將變得無效,嘗試訪問它會導致未定義行為。

2、刪除元素

從vector中移除元素后,該位置之后的所有元素及其對應的迭代器都會受到影響。

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.erase(vec.begin()); // 刪除第一個元素


    while (it != vec.end()) {
        std::cout << *it << " ";
        ++it;
    }
    std::cout << std::endl;


    return 0;
}

這里,erase()返回的是下一個有效元素的迭代器,確保了循環的安全性。

3、使用 clear() 方法清空容器

當調用clear()時,所有元素都會被刪除,但已分配的內存空間不會被釋放。這意味著容器的容量保持不變,但所有指向原元素的迭代器、指針或引用都將變得無效。

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin(); // 獲取開始位置的迭代器


    std::cout << "Before clear: Capacity = " << vec.capacity() << ", Size = " << vec.size() << std::endl;


    vec.clear(); // 清空向量


    std::cout << "After clear: Capacity = " << vec.capacity() << ", Size = " << vec.size() << std::endl;


    if (it != vec.end()) {
        // 這里會輸出錯誤信息,因為it已經失效
        std::cout << "Element: " << *it << std::endl;
    } else {
        std::cout << "Iterator is invalid after calling clear()." << std::endl;
    }


    return 0;
}

調用clear()后,迭代器it仍然指向原來的內存位置,但由于這些位置上的元素已被刪除,所以it實際上是無效的。為了安全起見,應該在clear()之后重新獲取迭代器。

4、使用 resize() 改變大小

減小尺寸:如果通過resize()減小vector的尺寸,那么超出新尺寸范圍的元素會被刪除,相應的迭代器也會失效。

增大尺寸:如果增加尺寸,則新增加的位置上的迭代器是未定義的(直到它們被初始化)。

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin() + 2; // 指向第三個元素


    std::cout << "Before resize: Capacity = " << vec.capacity() << ", Size = " << vec.size() << std::endl;
    std::cout << "Element at it before resize: " << *it << std::endl;


    vec.resize(2); // 減小尺寸到2


    std::cout << "After resizing to 2: Capacity = " << vec.capacity() << ", Size = " << vec.size() << std::endl;
    if (it != vec.end()) {
        // 這里可能會導致未定義行為,因為it已經失效
        std::cout << "Element at it after resize: " << *it << std::endl;
    } else {
        std::cout << "Iterator is invalid after resizing to 2." << std::endl;
    }


    vec.resize(6, 0); // 增大尺寸到6,并用0填充
    it = vec.begin() + 2; // 重新獲取有效迭代器


    std::cout << "After resizing to 6: Capacity = " << vec.capacity() << ", Size = " << vec.size() << std::endl;
    std::cout << "Element at it after resizing to 6: " << *it << std::endl;


    return 0;
}

5、使用 swap() 交換兩個 vector 的內容

當兩個vector之間進行數據交換時,它們各自的迭代器、指針和引用都將指向對方的數據結構。這意味著原來的迭代器將不再指向原來的數據。

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec1 = {1, 2, 3};
    std::vector<int> vec2 = {4, 5, 6};


    auto it1 = vec1.begin();
    auto it2 = vec2.begin();


    std::cout << "Before swap: vec1[0] = " << *it1 << ", vec2[0] = " << *it2 << std::endl;


    vec1.swap(vec2); // 交換兩個向量的內容


    std::cout << "After swap: vec1[0] = " << *it1 << ", vec2[0] = " << *it2 << std::endl;


    // 輸出顯示迭代器現在指向了交換后的數據
    std::cout << "it1 now points to: " << *it1 << std::endl;
    std::cout << "it2 now points to: " << *it2 << std::endl;


    return 0;
}

6、使用 assign() 重新賦值

assign()可以用來替換vector中的所有元素,這個過程類似于先調用clear()再插入新元素。因此,任何之前存在的迭代器都會失效。

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin();


    std::cout << "Before assign: Element at it = " << *it << std::endl;


    vec.assign(3, 0); // 用3個0替換原有元素


    if (it != vec.end()) {
        // 這里會導致未定義行為,因為it已經失效
        std::cout << "After assign: Element at it = " << *it << std::endl;
    } else {
        std::cout << "Iterator is invalid after assign." << std::endl;
    }


    // 重新獲取有效的迭代器
    it = vec.begin();
    std::cout << "New element at it: " << *it << std::endl;


    return 0;
}

vector刪除經典錯誤

當從vector中刪除一個元素時,所有指向該元素及其之后元素的迭代器都會失效。如果繼續使用這些迭代器,會導致未定義行為。

下面這個是新手最容易犯的一個錯誤:

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};


    for (auto it = vec.begin(); it != vec.end(); ++it) {
        if (*it == 3) {
            vec.erase(it); // 刪除元素3
        }
        std::cout << *it << " "; // 繼續使用失效的迭代器
    }
    std::cout << std::endl;


    return 0;
}

當*it == 3時,調用vec.erase(it)會刪除元素3。

erase()返回的是下一個有效元素的迭代器,但在這個例子中,it并沒有更新為新的迭代器,而是繼續遞增,導致訪問已失效的迭代器。

正確的做法是:

#include <iostream>
#include <vector>


int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};


    for (auto it = vec.begin(); it != vec.end(); ) {
        if (*it == 3) {
            it = vec.erase(it); // 更新迭代器
        } else {
            ++it; // 只有在沒有刪除元素的情況下才遞增迭代器
        }
    }


    for (const auto &val : vec) {
        std::cout << val << " ";
    }
    std::cout << std::endl;


    return 0;
}

總結:

為了避免由于迭代器失效引起的錯誤,我們在使用迭代器遍歷vector時,要避免在可能使迭代器失效的操作前后更新迭代器,或者盡量減少對vector的修改操作直到遍歷完成。此外,使用基于范圍的for循環(如for (auto &elem : vec))可以避免直接管理迭代器,從而簡化代碼并減少出錯的機會。

責任編輯:武曉燕 來源: CppPlayer
相關推薦

2021-04-15 08:01:27

Spring聲明式事務

2015-06-01 06:39:18

JavaJava比C++

2015-06-29 14:23:13

JavaC++慢很多

2024-08-01 08:29:45

Spring參數類型

2025-04-29 08:30:00

迭代器失效C++編程

2010-02-04 15:51:07

C++迭代器

2010-02-06 16:05:51

C++ Vector

2010-01-28 14:11:43

C++迭代器

2021-12-13 11:12:41

Spring事務失效

2024-12-01 18:29:42

2021-11-08 15:17:15

變量Defer 失效

2023-11-23 23:52:06

options請求瀏覽器

2022-09-14 19:50:22

事務場景流程

2022-06-27 07:23:44

MySQL常量優化

2021-06-04 09:17:13

JavaScriptBoolean函數

2009-12-01 11:39:39

配置路由器IP

2020-04-02 11:16:28

Linux進程高并發

2025-05-23 08:15:00

C++constexpr字面類型

2023-03-27 13:00:13

Javascript前端

2013-09-12 10:41:39

VDI部署
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 性高湖久久久久久久久3小时 | 国产美女网站 | 国产精品久久在线 | 国产日韩一区二区 | 日韩成人 | 亚洲在线一区二区 | 一区二区三区在线播放视频 | 四虎影院在线免费观看 | 国产午夜av片 | 岛国精品 | 久久久精| 久久久久精 | 毛片的网址 | 视频一区在线观看 | 国产精品揄拍一区二区久久国内亚洲精 | 日韩精品一区二区三区中文字幕 | 精品国产18久久久久久二百 | 色秀网站 | 中文字幕在线精品 | 国产精品区一区二区三区 | 天天射夜夜操 | 在线播放中文字幕 | 国产亚洲人成a在线v网站 | 99国产在线 | 福利片在线观看 | 四虎在线观看 | 操久久 | 国产精品一区二区久久久久 | 人妖一区 | 97综合在线 | 久久91视频 | 亚洲精品一区在线观看 | av天天澡天天爽天天av | 日韩在线播放一区 | 国产91观看 | 91精品国产色综合久久不卡98 | 国产精品久久久久久久久久久久久 | 久久精品无码一区二区三区 | 亚洲国产欧美日韩 | 成人午夜精品一区二区三区 | 超碰成人免费 |