STL_vector学习笔记


1. vector的底层原理

vector底层使用的是一个自动管理的动态数组,线性连续空间;vecotr的实现技术,关键在于其对大小的控制以及重新配置时数据移动效率。vector是动态空间,会随着新元素的加入,其内部机制会自行扩充空间以容纳新元素。

2. vector源码

vector的底层数据结构是:线性连续空间

iterator start;         // 记录目前使用空间的头
iterator finish;        // 记录目前使用空间的尾
iterator end_of_storage;// 记录目前可用空间的尾

在这里插入图片描述

3. vector的基本操作

3.1. 内存管理例子

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    // vector内存管理学习
    int i;
    vector<int> iv(3,9);
    cout << "size = " << iv.size() << endl;                 //  size = 3
    cout << "capacity = " << iv.capacity() << endl;         //  capacity = 3

    iv.push_back(1);
    cout << "size = " << iv.size() << endl;                 // size = 4         添加元素时,capacity<size,所以需要扩容
    cout << "capacity = " << iv.capacity() << endl;         // capacity = 6        

    iv.push_back(2);
    cout << "size = " << iv.size() << endl;                 // size = 5         添加元素时,capacity > size,所以不需要扩容
    cout << "capacity = " << iv.capacity() << endl;         // capacity = 6        

    iv.pop_back();
    cout << "size = " << iv.size() << endl;                 // size = 4         
    cout << "capacity = " << iv.capacity() << endl;         // capacity = 6        
   
    iv.push_back(3);
    cout << "size = " << iv.size() << endl;                 // size = 5         添加元素时,capacity > size,所以不需要扩容
    cout << "capacity = " << iv.capacity() << endl;         // capacity = 6        

    for(int i = 0;i < iv.size();i++)                        // 9 9 9 1 3
    {
        cout << iv[i] << " " ;
    }
    cout << endl;
    
    vector<int>::iterator ivite = find(iv.begin(),iv.end(),1);
    iv.erase(ivite);                                        // 擦去元素2

    cout << "size = " << iv.size() << endl;                 // size = 4         
    cout << "capacity = " << iv.capacity() << endl;         // capacity = 6
    
    for(int i = 0;i < iv.size();i++)                        // 9 9 9 3
    {
        cout << iv[i] << " " ;
    }
    cout << endl;

    iv.clear();                                             // clear()操作,内存并未释放,只是size=0
    cout << "size = " << iv.size() << endl;                 // size = 0         
    cout << "capacity = " << iv.capacity() << endl;         // capacity = 6
 
    vector<int> aaa;
    cout<< "新vector 初始内存 = " << aaa.size() << endl;
    cout<< "新vector 初始内存 = " << aaa.capacity() << endl;
    return 0;
}

3.2. 输出结果

[root@tianyiyi vector]# g++ -std=c++11 vector.cpp -o vector
[root@tianyiyi vector]# ./vector 
size = 3
capacity = 3
size = 4
capacity = 6
size = 5
capacity = 6
size = 4
capacity = 6
size = 5
capacity = 6
9 9 9 1 3 
size = 4
capacity = 6
9 9 9 3 
size = 0
capacity = 6

4. vector扩容问题

vector扩容(即动态增加大小)并非在源空间之后接续新空间(因为无法保证原有空间之后上游可供配置的空间),而是以原大小的两倍另外配置一块比较大的空间,然后将原内容拷贝过来,然后才开始在原内容之后构建新元素,并释放源空间。因此,对vector的任何操作,一旦引起空间重新配置,那么指向源vector的所有迭代器就都失效了。

5. 收集vector相关问题

5.1. 问:Vector底层数据结构

vector底层的数据结构是线性连续空间,其默认构造的方式是0, 之后插入按照1 2 4 8 16 二倍扩容(是按照当前capacity的倍数进行扩容)。注(GCC是二倍扩容,VS13是1.5倍扩容。)

5.2. 问:vector扩容原理概述

新增元素:Vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素;
对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了 ;

5.3. 问:主流STL实现的vector初始大小是多少

0

5.4. 问:remove和erase区别

vector中的remove是将要删除的元素放置在vector的尾部,但并不减少vectorsize
vectorerase的作用是删除掉某个位置position或一段区域,减少其size

5.5. 问:erase注意事项

erase可以删除vector容器中的一个或者一段元素,在进行单个元素删除后,传入的迭代器指向不变,仍然指向被删除元素的位置,而被删除元素之后的所有元素都镶嵌移动一位,也就是该迭代器实际上是指向了原来被删除元素的下一个元素。正因如此,如果删除了最后一个元素,那么该迭代器就不会指向vector数组了,而是变为野指针

// 错误写法!!!
vector<int>::iterator itr = v.begin()
while(itr != v.end())
{
    if(*v == 1)
    {
    	v.erase(itr);
    }
    itr++;	// 如果有删除,那么这个迭代器更新会出错
}

// 正确写法
vector<int>::iterator itr = v.begin()
while(itr != v.end())
{
    if(*v == 1)
    {
    	v.erase(itr);
    }
    else
    {
	    itr++;
	}
}

5.6. 问:push_back和emplace_back的区别

区别在于其底层实现机制不一样,
push_back向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中;而emplace_back在是实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

fantongl

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

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

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

打赏作者

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

抵扣说明:

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

余额充值