【c++】vector

简介: 【c++】vector

迭代器失效

我们之前说可能会不同编译器对迭代器的处理不同,使用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();
        
        
        
        }

目录
相关文章
|
1天前
|
C++
c++的学习之路:13、vector(2)
c++的学习之路:13、vector(2)
24 0
|
1天前
|
编译器 C++
C++:vector增删查改模拟实现
C++:vector增删查改模拟实现
56 0
|
1天前
|
存储 C++ 容器
【C++】vector的底层剖析以及模拟实现
【C++】vector的底层剖析以及模拟实现
|
1天前
|
编译器 C++ 容器
【C++练级之路】【Lv.7】【STL】vector类的模拟实现
【C++练级之路】【Lv.7】【STL】vector类的模拟实现
|
1天前
|
存储 算法 测试技术
C++:Vector的使用
C++:Vector的使用
|
1天前
|
存储 算法 C++
【C/C++ Vector容量调整】理解C++ Vector:Reserve与Resize的区别与应用
【C/C++ Vector容量调整】理解C++ Vector:Reserve与Resize的区别与应用
71 1
|
1天前
|
编译器 C++ Windows
【C++】vector问题解决(非法的间接寻址,迭代器失效 , memcpy拷贝问题)
不使用memcpy函数不就可以了,然后我们使用简单粗暴的赋值拷贝,这样就不会发生浅拷贝问题了!!!
16 1
|
1天前
|
算法 C++ 容器
【C++/STL】vector(常见接口、模拟实现、迭代器失效)
【C++/STL】vector(常见接口、模拟实现、迭代器失效)
11 0
|
1天前
|
存储 缓存 编译器
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
|
1天前
|
编译器 C++
【C++进阶(三)】STL大法--vector迭代器失效&深浅拷贝问题剖析
【C++进阶(三)】STL大法--vector迭代器失效&深浅拷贝问题剖析