【c++】vector

本文探讨了在使用G++编译器时,迭代器失效的问题以及如何通过示例代码理解其原理。作者提到vector库在不同编译器中的行为差异,以及如何通过完善vector模拟和错误处理来避免迭代器失效引发的错误。
摘要由CSDN通过智能技术生成

迭代器失效

我们之前说可能会不同编译器对迭代器的处理不同,使用vs vector库里的会强制检查,如果使用g++里面的,对于earse不会检查,由于我们vector的底层实现是看的g++的源码,所以我们不使用vs vector库,默认我们是在g++下编译,那这里g++针对迭代器失效不会报错吗???实际上会的,但是展示出来的错误,不会让你联想到迭代器失效,其实本质就是迭代器失效
举个例子,要在vector v1中删除偶数位(代码是上篇vector里面的,加一个测试函数)

  void test7()//测试函数
    {
        vector<int>v1;
        v1.push_back(1);
        v1.push_back(2);
        v1.push_back(3);
        v1.push_back(4);
        v1.push_back(5);
        vector<int>::iterator it = v1.begin();
        while (it != v1.end())
        {
            if (*it % 2 == 0)
                v1.erase(it);
                ++it;

        }
        for (auto e : v1)//范围for
        {
            cout << e << " ";


        }


    
    
    
    
    
    }

当你编译这段代码是时,你会发现没问题。

如果你将5去掉之后呢??
在这里插入图片描述

我们看到报错是因为pos<_finish???我们可以来模拟一下

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
那如果修改it<_finish不就行了??
在这里插入图片描述
结果是这样吗??
在这里插入图片描述
将1修改成10,发现结果不对了
在这里插入图片描述
如果是5个的话,最后一个是偶数也不对

总结:这些上述错误都是迭代器失效引起的,而结果可能不会让你联想到迭代器失效
其实我们可以通过earse返回下一个位置,就可以解决这里的问题辣
在这里插入图片描述
为什么string里面有迭代器失效吗??vector一般用的是原生迭代器,而string和list是别的方式,很少会出现迭代器失效

vector模拟的完善

     ~vector()//析构函数
        {
            delete[] _start;
            _start = _finish = _end_of_storage = nullptr;
        
        
        }
    vector(size_t n, const T& val = T())//用n个val来初始化
           
           {
            reserve(n);
            for (int i = 0; i < n; i++)
            {
                push_back(val);


            }
      
        }
  void test8()
    {
        vector<int>v1(10, 5);
        for (auto e : v1)//范围for
        {
            cout << e << " ";


        }
    
    
    }

在这里插入图片描述
在vs2013中左边是不行的,没有对三个值初始化
在这里插入图片描述
vs2019优化会处理这里的未初始化


使用迭代器用其他区间来初始化,这里也可以用string,没有用iterator来局限只能用vector

    template <class InputIterator>
        vector(InputIterator first, InputIterator end)
        {
            while (first != end)
            { 
                push_back(*first);
                first++;


            }
        
        
        
        
        }

在这里插入图片描述
在这里插入图片描述
也可以用string区间来初始化

void test9()
{
    vector<int>v1(10u, 5);
    string str = "hello";
    vector<int>v2(str.begin(), str.end());
    for (auto e : v1)//范围for
    {
        cout << e << " ";


    }
    cout << endl;
    for (auto e : v2)//范围for
    {
        cout << e << " ";


    }
   


}

在这里插入图片描述

用数组来初始化(用的上面第二种)

void test10()
{
    int arr[10] = { 25,6,3,78,45,12,36,42,1,15 };

    vector<int>v2(arr,arr+10);
   
    
    
 
    for (auto e : v2)//范围for
    {
        cout << e << " ";


    }



}

在这里插入图片描述


使用sort排序

#include<algorithm>
void test10()
{
    int arr[10] = { 25,6,3,78,45,12,36,42,1,15 };

    vector<int>v2(arr,arr+10);
    sort(v2.begin(), v2.end());
    sort(arr,arr+10);
    for (auto e : v2)//范围for
    {
        cout << e << " ";


    }
    cout << endl;
    for (auto e : arr)//范围for
    {
        cout << e << " ";


    }
    
    
 
  



}

在这里插入图片描述

拷贝构造

  vector(const vector<T>& v)
        {
            _start = new T[v.capacity()];
            memcpy(_start, v._start, sizeof(T) * v.size());
            _finish = _start + v.size();
            _end_of_storage = _start + v.capacity();
        
        
        
        }

vector的深拷贝和浅拷贝

内置类型的拷贝(浅拷贝)

   vector<int>v2(10u,5);
   vector<int>v3(v2);

  
    for (auto e : v2)//范围for
   {
        cout << e << " ";


   }
   cout << endl;
    for (auto e : v3)//范围for
    {
       cout << e << " ";

  }
   cout << endl;

}

自定义类型的拷贝

void test11()
{
     
    vector<std::string>v2(3,"11111111111111111111111");
    vector<std::string>v3(v2);


    for (auto e : v2)//范围for
    {
        cout << e << " ";


    }
    cout << endl;
    for (auto e : v3)//范围for
    {
        cout << e << " ";


    }
    cout << endl;







}

在这里插入图片描述

这里浅拷贝是按照字节一个一个拷贝,就会出现指向同一空间,当v3析构后,指向字符串那里的值已被释放,再次释放就会出错
所以我们必须使用深拷贝,修改拷贝构造

   vector(const vector<T> & v)
         
        {
            _start = new T[v.capacity()];
           /* memcpy(_start, v._start, sizeof(T) * v.size());*/
            for (int i = 0; i < v.size(); i++)
            {
                _start[i] = v._start[i];

            }
            _finish = _start + v.size();
            _end_of_storage = _start + v.capacity();
        
        
        
        }
   

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#小多子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值