c++学习(vector--迭代器失效)[8]

在C++中,迭代器失效可能导致程序错误或崩溃。当对容器(如std::vector)进行修改后,之前的迭代器可能无效。为防止这个问题,应使用容器提供的合法操作修改容器,避免直接操作迭代器,使用插入函数返回的新迭代器,以及在修改后重新获取迭代器。示例中展示了正确和错误地使用erase()和insert()的例子。
摘要由CSDN通过智能技术生成

在C++中,迭代器失效是指在对容器进行修改(插入、删除等)后,之前获取的迭代器可能会变得无效,不能再使用或者指向错误的元素。这是由于容器的内部结构发生了变化,导致迭代器指向的位置发生了改变。

迭代器失效可能会导致程序崩溃、访问非法内存或者产生未定义行为。为了避免迭代器失效问题,可以遵循以下几个注意事项:

  1. 合法操作:只使用容器提供的合法操作来修改容器,例如使用push_back()pop_back()等函数来添加或删除元素,而不是直接操作迭代器。

  2. 避免迭代器作为指针传递:尽量避免将迭代器作为指针传递给其他函数。因为在函数内部对容器进行修改可能会导致迭代器失效。

  3. 使用插入函数返回的迭代器:在插入元素时,使用插入函数返回的迭代器来获取插入后的位置,而不是之前的迭代器。

  4. 重新获取迭代器:在对容器进行修改后,如果需要继续使用迭代器,应该重新获取迭代器,而不是继续使用之前的迭代器。

  5. 使用容器提供的成员函数:使用容器提供的成员函数来进行迭代操作,例如使用begin()end()函数来获取容器的起始和结束迭代器。

需要注意的是,每种容器的迭代器失效规则可能会有所不同。在使用特定容器的迭代器时,应该查阅相关文档或参考C++标准来了解该容器的迭代器失效规则,并遵循相应的注意事项来避免迭代器失效问题。

使用std::vectorerase()insert()函数时示例

错误示例:

#include <iostream>
#include <vector>

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

    // 错误示例:使用erase()后未更新迭代器
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        if (*it == 3) {
            vec.erase(it);
        }
    }

    // 错误示例:使用insert()后未更新迭代器
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        if (*it == 2) {
            vec.insert(it, 6);
        }
    }

    // 输出修改后的vector
    for (const auto& num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

上述代码尝试在遍历vec时使用erase()insert()函数来删除和插入元素。然而,由于在这些操作之后未更新迭代器,导致迭代器失效,结果可能是未定义的行为或者崩溃。

正确示例:
erase返回删除数据的下一个位置的迭代器

#include <iostream>
#include <vector>

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

    // 正确示例:使用erase()后更新迭代器
    for (auto it = vec.begin(); it != vec.end();) {
        if (*it == 3) {
            it = vec.erase(it);
        } else {
            ++it;
        }
    }

    // 正确示例:使用insert()后更新迭代器
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        if (*it == 2) {
            it = vec.insert(it, 6);
            ++it;  // 插入后的元素也需要跳过
        }
    }

    // 输出修改后的vector
    for (const auto& num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

使用erase()insert()函数后更新了迭代器。在使用erase()函数后,我们将it更新为erase()函数的返回值,这是指向被删除元素之后的位置。在使用insert()函数后,我们将it递增一次,以跳过插入的元素。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值