【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();
        
        
        
        }

目录
相关文章
|
5月前
|
存储 编译器 C++
【C++】vector介绍+模拟实现
【C++】vector介绍+模拟实现
|
2月前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
90 4
|
1月前
|
存储 对象存储 C++
C++ 中 std::array<int, array_size> 与 std::vector<int> 的深入对比
本文深入对比了 C++ 标准库中的 `std::array` 和 `std::vector`,从内存管理、性能、功能特性、使用场景等方面详细分析了两者的差异。`std::array` 适合固定大小的数据和高性能需求,而 `std::vector` 则提供了动态调整大小的灵活性,适用于数据量不确定或需要频繁操作的场景。选择合适的容器可以提高代码的效率和可靠性。
65 0
|
1月前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
42 0
|
3月前
|
存储 C++ 索引
【C++打怪之路Lv9】-- vector
【C++打怪之路Lv9】-- vector
32 1
|
3月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化2
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
85 6
|
3月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化1
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
107 7
|
3月前
|
编译器 C++
【C++】—— vector模拟实现
【C++】—— vector模拟实现
|
3月前
|
编译器 C语言 C++
【C++篇】解密 STL 动态之魂:全面掌握 C++ vector 的高效与优雅
【C++篇】解密 STL 动态之魂:全面掌握 C++ vector 的高效与优雅
68 3
|
3月前
|
C++
【C++】C++ STL探索:Vector使用与背后底层逻辑(三)
【C++】C++ STL探索:Vector使用与背后底层逻辑