zoukankan      html  css  js  c++  java
  • 关于vector的erase删除操作的两种不同方法,在linux与visual studio的实现讨论

    关于vector的erase删除操作的两种不同方法,在linux与visual studio的实现讨论


    1.前言:

    最近在做某一个题时,用到了vector的删除操作,利用的是erase()函数删除符合条件的函数,然后和同学讨论的时候,同学给了一个写法,网上也搜到了一个写法,但是发现了问题。


    2.测试代码:

    定义一个vector 删除指定元素, 这里是删除1

    #include <vector>
    #include <iostream>
    using namespace std;
    
    int main() {
        vector <int> arr; 
        arr.push_back(1);
        arr.push_back(2);
        arr.push_back(3);
        arr.push_back(4);
        arr.push_back(5);
    
        for (auto i = arr.begin(); i != arr.end(); i++) {           // 第一种写法
            if (*i == 1) {
                i = arr.erase(i);
                i--;
            }
        }
    
         for (auto i = arr.begin(); i != arr.end();) {           // 第二种写法
            if (*i == 1) {
                i = arr.erase(i);
            } else {
                i++;
            }
         }
    
    
    
        for (auto i = arr.begin(); i != arr.end(); i++) {        //输出
            cout << *i << " ";
        }
        cout << endl;
    
    
    
        return 0;
    }

    3.讨论


    这两种写法, 看起来是基本相同的,基本想法就是每一次循环 删除了迭代器那么不自增迭代器,反之,则自增迭代器, 实则不然,如果一上来就删除首元素, 那么问题就来了 方法一的i在自减之后不是出了小于arr.begin()了吗。别急我们看下面的实践。


    4.测试

    ubuntu

    在ubuntu下可以运行而且不出错
    这里写图片描述

    这里进入gdb调试 查看迭代器i的变化

    这里写图片描述
    **在删除元素后 迭代器自减后竟然是有地址的 此时地址是arr.begin()的前面一个地址, 也就是说i可以变成
    arr.begin() - 1**

    这里写图片描述
    迭代器自加后 迭代器变成了arr.begin()

    这里写图片描述

    visual studio

    运行时错误,出错在 i–;
    因为i–后 i变成了arr.begin() - 1 而visual studio不支持这样的写法,所以报错
    这里写图片描述

    这里写图片描述

    5.总结

    vector如果简单想象成数组arr的话,在首元素i–,i = (arr - 1),但我们并没有在这个状态下解引用。然后i++加回去又回到可解引用的地址值,不出事也是可以理解的, gnu对list的实现是双向循环链表 ++list.end() 后就变成 list.begin()。但vs会assert说越界

  • 相关阅读:
    lambda表达式——sort和compare进行高级排序
    guava包的应用总结
    ffmpeg源码编译安装(Compile ffmpeg with source) Part 1 : 通用部分
    Notes : <Hands-on ML with Sklearn & TF> Chapter 4
    Notes : <Hands-on ML with Sklearn & TF> Chapter 3
    scxml-1
    redis
    Async Actions using Coroutines(异步行为使用协程,协同程序)
    Pass additional arguments during initialization and/or construction
    Wraping legacy code
  • 原文地址:https://www.cnblogs.com/qq874455953/p/9589222.html
Copyright © 2011-2022 走看看