程序员成长之旅——vector容器

vector的常见使用

vector的定义

构造函数声明

vector()	//无参构造
vector(size_type n,const value_type& val = value_type()) //构造并初始化n个val
vector(const vector& x) 	//拷贝构造
vector(InputIterator first,InputIterator last);	//使用迭代器进行初始化构造
vector iterator的使用
iterator的使用
begin()	//获取第一个数据位置的iterator
end()	//获取最后一个数据的下一个位置的iterator
rbegin()	//获取最后一个数据位置的reverse_iterator
rend()	//获取第一个数据前一个位置的reverse_iterator
cbegin()	//获取第一个数据位置的const_iterator
cend()	//获取最后一个数据的下一个位置的const_iterator

在这里插入图片描述

vector增删查改
void push_back(const value_type& val);	//尾插
void pop_back();	//尾删
Inputlterator find(InputIterator first,InputIterator last,const T& val);	//查找
iterator insert(iterator position,const value_type& val);	//在position之前插入val
iterator erase(iterator position)	//删除position位置的数据
void swap(vector& x);	//交换两个vector的数据空间
reference operator[](size_type n);	//像数组一样访问

vector常见问题

vector的底层实现原理以及实现机制

vector简介
关于vector简单的说的话就是一个动态增长的数组,里面有一个指针指向一片连续的内存空间,当空间装不下要容纳的数据的时候会自动申请一片更大的空间(空间配置器)将原来的数据拷贝到新的空间,然后就会释放旧的空间。当删除的时候空间并不会释放,只是清空了数据。
vector和数组的区别
vector的数据安排以及操作方式与数组非常相似,两者唯一区别在于空间运用的灵活性,数组是静态空间一旦配置了就不能在改变大小,如果要增容的话,就要把数据搬到新的数组里面,然后再把原来的空间释放掉还给操作系统。vector是动态的随着元素的增加,它的内部机制会自动的扩充空间来容纳新的元素。因此,vector的运用对于内存的合理利用与运用的灵活性有很大的帮助,我们不必害怕空间不足而一开始开辟一块很大的内存。
vector实现机理
vector的实现技术,关键在于对大小的控制以及重新配置时的数据移动效率。一旦vector的旧空间满载了,如果客户端每新增加一个元素,vector的内部只是扩充了一个元素空间,其实这样是比较不明智的。因为所谓的扩充空间(无论多大),过程都是配置新空间----数据移动----释放旧空间,成本还是比较高的。vector维护是一个连续的线性空间,所以vector支持随机访问。
vector容易犯的错误
在vector的动态增加大小的时候,并不是在原有的空间上持续增加新的空间(无法保证原空间的后面还有可供配置的空间),而是以原大小的两倍另外配置一块较大的空间,然后将原来的内容拷贝过来,并释放原来的空间。因此,对vector的任何操作一旦引起了空间的重新配置,指向原vector的所有迭代器会都失效了,这是比较容易犯的一个错误。

vector空间增长问题
size()	//获取数据个数
capacity()	//获取容量大小
empty()	//判断是否为空
void resize(size_type n,value_type val = value_type());	//改变vector的size
void reserve(size_type n);	//改变vector放入的capacity
  • capacity的代码在vs和g++下分别运行会发现,vs下的capacity是按1.5倍增长的,g++是按2位增长的。因此它具体的增长多少是根据具体的需求定义的。
  • reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
  • resize在开空间的同时还会进行初始化,影响size
vector< char >和string的区别
	vector<char> vch;
	vch.push_back('\0');
	cout<<vch.size()<<endl;//输出1
	
	string s3="";
	cout<<s3.size()<<endl;//输出0
	
	string s4="\0";
	cout<<s4.size()<<endl;//输出0

string类型会默认结尾是一个空字符,如果一个string只含有一个空字符,则该string为空。vector则不同,含有一个空字符后,就不在是空的。总的来说:两种类型不同,还有就是string是以‘\0’结尾,vector不是。

vector迭代器失效问题

由于迭代器的类型是:

typedef T* iterator

它是一个指针。

//insert/erase导致的迭代器失效
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

int main()
{
	int a[] = {1,2,3,4};
	vector<int> v(a,a + sizeof(a) / sizeof(int));
	//使用find查找3所在位置的iterator
	vector<int>::iterator pos = find(v.begin(),v.end(),3);
	// 删除pos位置的数据,导致pos迭代器失效。
	v.erase(pos);
	cout << *pos << endl; // 此处会导致非法访问
	// 在pos位置插入数据,导致pos迭代器失效。
	// insert会导致迭代器失效,是因为insert可
	// 能会导致增容,增容后pos还指向原来的空间,而原来的空间已经释放了。
	pos = find(v.begin(), v.end(), 3);
	v.insert(pos, 30);
	cout << *pos << endl; // 此处会导致非法访问
	return 0;
}

// 常见的迭代器失效的场景
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
	int a[] = { 1, 2, 3, 4 };
	vector<int> v(a, a + sizeof(a) / sizeof(int));
	// 实现删除v中的所有偶数
	// 下面的程序会崩溃掉,如果是偶数,erase导致it失效
	// 对失效的迭代器进行++it,会导致程序崩溃
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
			v.erase(it);
			++it;
	}
	// 以上程序要改成下面这样,erase会返回删除位置的下一个位置
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
			it = v.erase(it);
		else
			++it;
	}
	return 0;
}

迭代器失效:
auto it = v.begin(); it实际已经指向vector底层空间的起始位置
v.push_back(data);
通过it迭代器访问vector中的元素—>可能会引起代码崩溃
1.如果底层空间的改变—push_back/insert resize/reserve swap assign
2.erase(pos)–pos的迭代器失效 pos–>vector中的某个位置–>T类型对象

解决迭代器失效: 给迭代器重新赋值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

从零出发——

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

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

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

打赏作者

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

抵扣说明:

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

余额充值