跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

C++ Vector 容器详解

C++ 标准库中的 vector 容器。内容包括 vector 的基本概念、动态扩容机制、多种构造方式、迭代器使用(begin/end/rbegin/rend)、容量管理函数(size/capacity/reserve/resize/shrink_to_fit)、元素访问操作(operator[]/at/front/back)以及修改操作(assign/push_back/pop_back/insert/erase/swap/clear)。重点讲解了 vector 迭代器失效的场景及正确处理方法,并对比了 reserve 与 resize 的区别。适合希望深入理解 C++ 动态数组特性的开发者阅读。

灭霸发布于 2026/3/30更新于 2026/9/1078 浏览

一、vector 的介绍

vector - C++ Reference

1.1 vector 是表示可变大小数组的序列容器。

1.2 和数组一样,vector 也同样使用连续的存储空间来存储元素。也就意味着可以通过下标访问 vector 的每个元素,访问效率和数组一样高效。但和数组不同的是,vector 的 size 是可以动态改变的,并且容器会自动处理存储大小。

1.3 本质上,vector 使用动态分配数组来存储它的元素。当新元素插入时,原数组为了增加存储空间需要被重新分配大小。其做法是,分配一个新数组,然后将原数组中所有元素拷贝到新数组中。但这是一个时间消耗很大的操作,因此,每当有新元素插入时,vector 并不会每次都选择重新分配数组大小。

1.4 vector 分配空间的策略:vector 会分配一些额外的空间以适应可能的元素插入操作,因为存储空间要比实际需要的存储空间更大,不同的编译器会采用不同的策略来权衡空间的使用和重新分配。在 VS2022 下 vector 每次是以 1.5 倍的方式进行扩容,g++ 则是以 2 倍的方式进行扩容。

vector<int> v; int ca = v.capacity(); for (int i = 0; i < 100; i++) { v.push_back(i); if (ca != v.capacity()) { //每次扩容后就打印之前的容量,然后更新容量 cout << ca << endl; ca = v.capacity(); } }

1.5 因此,相较于数组,vector 会消耗更多的内存以适应动态增长和高效的内存管理。

1.6 和其他的动态顺序容器相比 (deques, list 和 forward_list),vector 在访问元素时更高效,在末尾插入和删除元素的效率也相对高效。对于其他位置的插入和删除元素,vector 的操作效率会更低,并且迭代器和引用的一致性不如 list 和 forward_list。

二、vector 的使用

2.1 构造函数 (constructor)

allocator 指的是内存池,是 C++ 内存分配的一个类模板,allocator_type 是一个模板参数。explicit 代表该构造函数禁止隐式类型转换。

2.1.1 默认构造
//默认构造 explicit vector(const allocator_type& alloc = allocator_type()); 

使用:

//构造一个 int 类型的 vector vector<int> vi; //构造一个 double 类型的 vector vector<double> vd; //构造一个 string 类型的 vector vector<string> vs; //构造一个 vector<int> 类型的 vector vector<vector<int>> vv;
2.1.2 使用 n 个 val 进行构造 vector
//使用 n 个 val 构造 vector explicit vector(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()); 

使用:

//用 5 个 3 构造 vi vector<int> vi(5, 3); //用 4 个 2.0 构造 vd vector<double> vd(4, 2.0); //用 3 个"hehe"构造 vs vector<string> vs(3, "hehe"); //用 2 个 vi 构造 vv vector<vector<int>> vv(2,vi);
2.1.3 使用一段迭代器区间构造 vector
//使用一段迭代器区间进行构造 vector template<class InputIterator> vector(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); 

使用:

vector<int> v1(3, 3); //用 v1 的 begin() 到 end() 这段迭代器区间构造一个 int 类型的 v2 vector<int> v2(v1.begin(), v1.end()); //用 v1 的 begin() 到 end() 这段迭代器区间构造一个 char 类型的 v3 vector<char> v3(v1.begin(), v1.end()); string s1("hello"); //使用 s1 的 begin() 到 end() 构造一个 int 类型的 v4 vector<int> v4(s1.begin(), s1.end()); vector<double> v5(v1.begin(), v1.end());

【注意】使用迭代器区间构造 vector 时可以使用其他容器的迭代器区间去初始化一个 vector,但数据类型需要匹配。

例如:无法使用 vector 类型的 vector 迭代器区间构造 int 类型的 vector。

vector<int> v1(3, 3); vector<vector<int>> v2(2, v1); //error C2440: '初始化': 无法从'std::vector<int,std::allocator<int>>'转换为'_Objty' vector<int> v3(v2.begin(), v2.end());
2.1.4 拷贝构造
//拷贝构造 vector(const vector& x);

使用:

vector<int> v1(3, 3); //使用 v1 拷贝构造 v2 vector<int> v2(v1); //使用 v1 拷贝构造 v3 vector<int> v3 = v1;
2.1.5 使用数组构造 vector
int a1[] = { 1,2,3,4 }; vector<int> v1(a1, a1 + 4); //v1:{1,2,3,4} float a2[] = { 1.1,2.2,3.3,4.4 }; vector<float> v2(a2, a2 + 3); //v2:{1.10000002,2.20000005,3.29999995} string a3[] = { "hehe","hello","haha" }; vector<string> v3(a3, a3 + 3); //v3:{"hehe","hello","haha"} vector<char> v4 = { 'a','b','c','d' }; //v4:{'a','b','c','d'} vector<int> v5{1,2,3,4}; //v5:{1,2,3,4}

2.2 析构函数 (destructor)

编译器会自动调用。

~vector();

2.3 赋值重载 (operator=)

vector& operator=(const vector& x); 

使用:

vector<int> v1(3, 3); //v1:{3,3,3} vector<int> v2(3, 2); //v2:{2,2,2} //v1 和 v2 都存在,把 v1 赋值给 v2 v2 = v1; //v2:{3,3,3} //将一个匿名空对象赋值给 v1 v1 = vector<int>(); //v1:{}

2.4 迭代器 (iterator)

2.4.1 begin

获取 vector 第一个数据位置的迭代器。

iterator begin(); const_iterator begin() const;

使用:

int a[] = { 1,2,3}; vector<int> v1(a,a+3); vector<int>::iterator it1 = v1.begin(); vector<int> v2 = { 2,3,4}; vector<int>::iterator it2 = v2.begin(); const vector<int> v3 = { 3,4,5}; vector<int>::const_iterator cit3 = v3.begin(); //error,const 对象无法使用非 const 迭代器 //vector<int>::iterator it3 = v3.begin();
2.4.2 end

获取 vector 最后一个数据的下一个位置的迭代器。

iterator end(); const_iterator end() const;

使用:

int a[] = { 1,2,3}; vector<int> v1(a,a+3); vector<int>::iterator eit1 = v1.end(); vector<int> v2 = { 2,3,4}; vector<int>::iterator eit2 = v2.end();
2.4.3 rbegin

获取 vector 最后一个数据位置的迭代器。

reverse_iterator rbegin(); const_reverse_iterator rbegin() const;

使用:

int a[] = { 1,2,3}; vector<int> v1(a,a+3); vector<int>::reverse_iterator rbit1 = v1.rbegin(); vector<int> v2 = { 2,3,4}; vector<int>::reverse_iterator rbit2 = v2.rbegin(); //使用 const 版本的 rbegin 迭代器 const vector<int> v3 = { 3,4,5}; vector<int>::const_reverse_iterator crbit3 = v3.rbegin();
2.4.4 rend

获取 vector 第一个数据的前一个位置的迭代器。

reverse_iterator rend(); const_reverse_iterator rend() const;

使用:

int a[] = { 1,2,3}; vector<int> v1(a,a+3); vector<int>::reverse_iterator reit1 = v1.rend(); vector<int> v2 = { 2,3,4}; vector<int>::reverse_iterator reit2 = v2.rend(); //使用 const 版本的 rbegin 迭代器 const vector<int> v3 = { 3,4,5}; vector<int>::const_reverse_iterator creit3 = v3.rend();
2.4.5 迭代器总结
vector<int> v1 = { 1,2,3,4,5 }; vector<int>::iterator bit = v1.begin(); vector<int>::iterator eit = v1.end(); vector<int>::reverse_iterator rbit = v1.rbegin(); vector<int>::reverse_iterator reit = v1.rend();

迭代器使用场景

1.直接使用迭代器进行遍历:

//正向迭代器遍历 while (bit != eit) { cout << *bit << " "; //1 2 3 4 5 bit++; } cout << endl; //反向迭代器遍历 while (rbit != reit) { cout << *rbit << " "; //5 4 3 2 1 rbit++; }

2.范围 for 遍历

//范围 for 遍历 for (auto e : v1) { cout << e << " "; //1 2 3 4 5 } cout << endl;

【注意】范围 for 只能正向遍历,无法反向遍历。

2.5 容量相关的成员函数 (capacity)

2.5.1 size

返回 vector 内有效数据个数。

size_type size() const;

使用:

vector<int> v1(5, 3); cout << v1.size() << endl; //5
2.5.2 max_size

返回 vector 能申请的最大空间的大小,但是是一个固定的值,且不同平台上值也可能会不同。

size_type max_size() const;

使用:

vector<int> v; cout << v.max_size() << endl; //VS2022,32 位,值是 1073741823
2.5.3 resize

改变 vector 的 size 大小。

void resize(size_type n, value_type val = value_type());

参数介绍: n:新的 size 大小。 val:n 比原来的 size 大时,需要尾插的数据,默认为 0。

使用:

vector<int> v(10,2); //v:{2,2,2,2,2,2,2,2,2,2} cout << v.size() << endl; //size:10 cout << v.capacity() << endl; //capacity:10 //当 n 比 size 小时 v.resize(3); //v:{2,2,2} cout << v.size() << endl; //size:3 cout << v.capacity() << endl; //capacity:10 //当 n 比 size 大,但小于 capacity 时 v.resize(6, 1); //v:{2,2,2,1,1,1} cout << v.size() << endl; //size:6 cout << v.capacity() << endl; //capacity:10 //当 n 比 capacity 还大时 v.resize(12); //v:{2,2,2,1,1,1,0,0,0,0,0,0} cout << v.size() << endl; //size:12 cout << v.capacity() << endl; //capacity:15

注: n 小于当前 size 时,会直接将有效数据个数减少到 n。 当 n 大于当前 size,但小于当前 capacity 时,会尾插 val,直到 size 变成 n,val 如果不传,默认为 0。 当 n 大于当前 capacity 时,会先扩容,然后尾插 val,直到 size 变成 n。

2.5.4 capacity

返回 vector 当前容量的大小。

size_type capacity() const;

使用:

vector<int> v; v.resize(12); //v:{0,0,0,0,0,0,0,0,0,0,0,0} cout << v.capacity() << endl; //12
2.5.5 reserve

改变当前 vector 的 capacity。

void reserve(size_type n);

使用:

vector<int> v(5,2); //v:{2,2,2,2,2} cout << v.size() << endl; //size:5 cout << v.capacity() << endl; //capacity:5 v.reserve(3); //v:{2,2,2,2,2} cout << v.size() << endl; //size:5 cout << v.capacity() << endl; //capacity:5 v.reserve(7); //v:{2,2,2,2,2} cout << v.size() << endl; //size:5 cout << v.capacity() << endl; //capacity:7 v.reserve(10); cout << v.size() << endl; //size:5 cout << v.capacity() << endl; //capacity:10

注:当 n 小于当前 capacity 时,reserve 只会发出一个缩容的申请,但实际上并不会缩容,当 n 大于当前 capacity 时 reserve 会进行扩容。并且 reserve 全程不会对 size 有任何影响。

2.5.6 reserve 和 resize 的区别

reserve 只负责开空间,如果在明确知道需要多少空间的情况下使用 reserve 可以避免多次扩容的消耗。

resize 在开空间的情况下还会进行初始化,会影响 size。

vector 中 reserve 开出的空间无法使用 operator[] 等成员访问操作符进行访问,但 resize 开出的空间可以使用成员访问操作符进行访问和修改等操作。

vector<int> v1; v1.resize(10); v1[5] = 4; //v1:{0,0,0,0,0,4,0,0,0,0} vector<int> v2; v2.reserve(10); //会直接报错 //v2[5] = 4;
2.5.7 shrink_to_fit

缩小当前 capacity 到当前 size 大小。

void shrink_to_fit();

使用:

vector<int> v; v.resize(10); //v:{0,0,0,0,0,0,0,0,0,0} cout << v.size() << endl; //size:10 cout << v.capacity() << endl; //capacity:10 v.resize(5); //v:{0,0,0,0,0} cout << v.size() << endl; //size:5 cout << v.capacity() << endl; //capacity:10 //缩容操作 v.shrink_to_fit(); //v:{0,0,0,0,0} cout << v.size() << endl; //size:5 cout << v.capacity() << endl; //capacity:5

注:shrink_to_fit 的操作一般是在异地开辟一块和当前 size 大小一样的空间,然后将旧数据拷贝到新的空间里,最后释放旧空间,是属于一种用时间换空间的方式。

2.6 访问操作相关的成员函数 (element access)

2.6.1 operator[]
reference operator[](size_type n); const_reference operator[](size_type n) const;

使用:

//非 const 版本既能访问也能修改 vector<string> v{ "hehe","haha","hihi","hello" }; //访问 for (size_t i = 0; i < v.size(); i++) { cout << v[i] << " "; //hehe haha hihi hello } cout << endl; //修改 v[2] = "gulugulu"; for (size_t i = 0; i < v.size(); i++) { cout << v[i] << " "; //hehe haha gulugulu hello } cout << endl; //const 版本的只能进行访问 const vector<string> v2{ "hehe","haha","hihi","hello" }; //访问 for (size_t i = 0; i < v2.size(); i++) { cout << v2[i] << " "; //hehe haha hihi hello } //const 版本的 operator[] 无法进行修改操作 //error C2678: 二进制'=': 没有找到接受'const _Ty'类型的左操作数的运算符 (或没有可接受的转换) //v2[2] = "gulugulu";

注:operator[] 在访问时会进行断言,只能访问在 size 以内的有效数据,如果 n 不在 [0,size) 这段区间内则会直接报错。但断言有个缺点,在 release 下不会起作用。

vector<int> v{ 1,2,3,4 }; //直接报 assert 相关的错误 v[-1]; v[7];
2.6.2 at
reference at(size_type n); const_reference at(size_type n) const;

使用:

vector<int> v{ 1,2,3,4 }; for (size_t i = 0; i < v.size(); i++) { cout << v.at(i) << " "; //1 2 3 4 } cout << endl;

注:和 operator[] 不同的是,at 在访问时如果出现了越界访问的情况会直接抛出异常。

//会直接抛出异常 v.at(10);
2.6.3 front

访问 vector 的首元素。

reference front(); const_reference front() const;

使用:

vector<int> v1{ 1,2,3,4 }; cout << v1.front() << endl; //1 vector<int> v2; //如果 v2 为空,则会报断言错误 cout << v2.front() << endl;

注:如果 vector 为空,会直接报断言错误。

2.6.4 back

访问 vector 的尾部元素。

reference back(); const_reference back() const;

使用:

vector<int> v{ 1,2,3,4 }; cout << v.back() << endl; //4 v.back() += 5; cout << v.back() << endl; //9 vector<int> v2; //直接报断言错误 v2.back();

注:如果 vector 对象为空对象,那么使用 back 访问时会直接报断言错误。

2.7 修改相关的成员函数 (modifiers)

2.7.1 assign

使用一段迭代器区间覆盖当前对象的内容,或使用 n 个 val 覆盖当前对象里面的内容。

//使用一段迭代器区间进行覆盖 template<class InputIterator> void assign(InputIterator first, InputIterator last); //使用 n 个 val 进行覆盖 void assign(size_type n, const value_type& val);

使用:

vector<int> v1{ 1,2,3,4 }; vector<int> v2{ 5,6 }; vector<int> v3{ 7,8,9,10,11 }; //v2:size:2,v2:capacity:2 cout <<"v2:size:" << v2.size() << "," << "v2:capacity:" << v2.capacity() << endl; v2.assign(v1.begin(), v1.end()); //v2:{1,2,3,4} //使用 v1 覆盖 v2 后 //v2:size:4,v2:capacity:4 cout << "v2:size:" << v2.size() << "," << "v2:capacity:" << v2.capacity() << endl; //v3:size:5,v3:capacity:5 cout << "v3:size:" << v3.size() << "," << "v3:capacity:" << v3.capacity() << endl; v3.assign(v1.begin(), v1.end()); //使用 v1 覆盖 v3 后 //v3:size:4,v3:capacity:5 cout << "v3:size:" << v3.size() << "," << "v3:capacity:" << v3.capacity() << endl;

【注意】使用 assign 过程中旧数据会全部被新数据覆盖,size 和 capacity 都有可能会变化。

2.7.2 push_back

尾插一个数据。

void push_back(const value_type& val);

使用:

vector<int> v{ 1,2,3,4 }; cout << v.size() << endl; //4 cout << v.capacity() << endl; //4 v.push_back(5); //v:{1,2,3,4,5} cout << v.size() << endl; //5 cout << v.capacity() << endl; //6
2.7.3 pop_back

尾删一个数据。

void pop_back();

使用:

vector<int> v{ 1,2,3,4 }; cout << v.size() << endl; //4 cout << v.capacity() << endl; //4 v.pop_back(); //v:{1,2,3} cout << v.size() << endl; //3 cout << v.capacity() << endl; //4

注:如果对象为空,使用 pop_back 时会报断言错误。

vector<int> v2; //报断言错误 v2.pop_back();
2.7.4 insert

在 position 位置之前插入一个 val,在 position 位置之前插入 n 个 val 或在 position 位置之前插入一段迭代器区间的数据。

//在 pos 位置插入 val iterator insert(iterator position,const value_type& val); //在 pos 位置插入 n 个 val void insert(iterator position, size_type n, const value_type& val); //在 pos 位置插入一段迭代器区间 template<class InputIterator> void insert(iterator position, InputIterator first, InputIterator last);

使用:

在 vector 里面没有 find 这个函数,但在算法库 algorithm 里面有一个 find 函数,所有容器几乎都可以使用。找不到会返回 last 位置的迭代器。但 string 里面还是需要自己设计单独的 find 函数,因为算法库里面的 find 无法支持 string 单独需要的查找字符串功能。

template <class InputIterator, class T> InputIterator find (InputIterator first, InputIterator last, const T& val);
vector<int> v1{ 1,2,3,4,5 }; vector<int> v2{ 5,6,7 }; vector<int>::iterator it = find(v1.begin(),v1.end(),3); //在 3 这个位置插入一个 30 it = v1.insert(it, 30); for (auto e : v1) { cout << e << " "; //1 2 30 3 4 5 } cout << endl; cout << *it << endl; //30 //在 30 的位置上插入 2 个 20 v1.insert(it, 2, 20); for (auto e : v1) { cout << e << " "; //1 2 20 20 30 3 4 5 } cout << endl; it = find(v1.begin(), v1.end(), 4); //在 4 的位置上插入 v2 的 begin 到 end 这段迭代器区间的内容,[begin,end) v1.insert(it, v2.begin(), v2.end()); for (auto e : v1) { cout << e << " "; //1 2 20 20 30 3 5 6 7 4 5 } cout << endl;

注:单独插入一个 val 值时可以使用迭代器去接收返回后的迭代器,要插入的迭代器区间的一段内容时迭代器区间是左闭右开的,[first,last)。

2.7.5 erase

删除 position 位置上的值、删除迭代器区间 [first,last) 的值。

//删除 position 位置的值 iterator erase(iterator position); //删除 [first,last) 区间的值 iterator erase(iterator first, iterator last);

使用:

vector<int> v1{ 1,2,3,4,5,6 }; vector<int>::iterator it = find(v1.begin(), v1.end(), 5); //删除 5 v1.erase(it); //v1:{1,2,3,4,6} //删除 [2,6) 区间内的值 auto first = find(v1.begin(), v1.end(), 2); auto last = find(v1.begin(), v1.end(), 6); v1.erase(first, last); //v1:{1,6}

注:删除一段迭代器区间内的值,区间是左闭右开。

2.7.6 swap

交换两个 vector 是数据空间。

void swap(vector& x);

使用:

vector<int> v1{ 1,2,3 }; vector<int> v2{ 2,3,4 }; v1.swap(v2);

注:swap 交换会直接将成员变量的地址进行交换。

2.7.7 clear

清空 vector 内的所有元素,使 vector 的 size 变为 0。

void clear();

使用:

vector<int> v1{ 1,2,3,4 }; cout << v1.size() << endl; //4 cout << v1.capacity() << endl; //4 v1.clear(); cout << v1.size() << endl; //0 cout << v1.capacity() << endl; //4

注:clear 只会清空 vector 内部的有效数据,但并不会销毁和释放 vector 申请的空间。

2.8 vector 迭代器失效问题

迭代器的主要作用就是让算法不用关心底层的数据结构,其底层实际上就是一个指针,或是对指针进行了封装。比如:vector 的迭代器就是原生指针 T。因此迭代器失效实际上就是迭代器所指向的底层空间已经被销毁了,如果继续使用该迭代器去操作对应的底层空间,导致的后果就是程序崩溃。*

对于 vector 可能会导致其迭代器失效的操作有:

1.会进行扩容的操作,都有可能会导致其迭代器失效。例如:resize、reserve、insert、assign、push_back 等。

resize:使有效元素增加时可能会进行扩容。

vector<int> v{ 1,2,3,4,5 }; cout << v.size() << endl; //5 cout << v.capacity() << endl; //5 vector<int>::iterator it = v.begin(); cout << *it << endl; //1 //将有效数据个数变成 10 个 v.resize(10, 1); cout << v.size() << endl; //10 cout << v.capacity() << endl; //10 //会直接崩溃报错 //cout << *it << endl;

reserve:当传入的 n 大于当前 capacity 时会进行扩容。

vector<int> v{ 1,2,3,4,5 }; cout << v.size() << endl; //5 cout << v.capacity() << endl; //5 vector<int>::iterator it = v.begin(); cout << *it << endl; //1 //将空间扩容至 10 v.reserve(10); cout << v.size() << endl; //5 cout << v.capacity() << endl; //10 //会直接崩溃报错 //cout << *it << endl;

insert:当插入元素时可能会出现空间不够进行扩容的情况。

vector<int> v{ 1,2,3,4,5 }; cout << v.size() << endl; //5 cout << v.capacity() << endl; //5 vector<int>::iterator it = v.begin(); cout << *it << endl; //1 //在第三个数据的位置插入一个 30 v.insert(it + 2, 30); cout << v.size() << endl; //6 cout << v.capacity() << endl; //7 //会直接崩溃报错 //cout << *it << endl; //1

assign:assign 覆盖时如果新对象空间大于被覆盖对象的空间,那么被覆盖的对象就会进行扩容。

vector<int> v{ 1,2,3,4,5 }; cout << v.size() << endl; //5 cout << v.capacity() << endl; //5 vector<int>::iterator it = v.begin(); cout << *it << endl; //1 vector<int> v2{ 2,3,4,5,6,7,8,9 }; //使用 v2 的 begin 到 end 迭代器区间内容覆盖 v v.assign(v2.begin(),v2.end()); cout << v.size() << endl; //8 cout << v.capacity() << endl; //8

push_back:尾插在空间不够的情况下也可能会进行扩容。

vector<int> v{ 1,2,3,4,5 }; cout << v.size() << endl; //5 cout << v.capacity() << endl; //5 vector<int>::iterator it = v.begin(); cout << *it << endl; //1 //尾插一个 6 v.push_back(6); cout << v.size() << endl; //8 cout << v.capacity() << endl; //8

2.指定位置的元素删除操作也可能会导致迭代器失效。例如:erase。

erase 只是删除指定位置的数据,并不会导致空间的扩容,理论上来说迭代器不会失效,但如果 pos 刚好是 end 的前一个位置,且需要删除 end 前一个位置的数据,那么 erase 删除后 pos 的位置就和 end 的位置相同,此时 pos 迭代器就会失效。

例如下面这段代码:

vector<int> v{ 2,2,3,4,5,6 }; auto it = v.begin(); //删除所有偶数 while (it != v.end()) { if (*it % 2 == 0) { v.erase(it); } it++; }

如果将 v 拆分成{1,2,3}、{1,2,3,4,5}、{2,2,3,4,5}在 linux 平台 g++ 编译环境下会出现三种结果,分别是正常打印结果{1,3,5}、崩溃报错、错误打印结果{2,3,5}。

注:在这种情况下 erase 迭代器 it 指向的位置的值时,不仅结果出错,甚至程序都会崩溃。

上面代码的正确写法:在 erase 后需要重新使用 it 进行接收 erase 返回的迭代器。

vector<int> v{ 2,2,3,4,5,6 }; auto it = v.begin(); //删除所有偶数 while (it != v.end()) { if (*it % 2 == 0) { it= v.erase(it); } else { it++; } }

总结:在 VS 平台下,编译器会认为 insert 和 erase 后的迭代器都会失效。解决办法:在使用迭代器之前重新对迭代器进行赋值,例如使用迭代器接收 insert 和 erase 的返回值。

2.9 其他

vector 并没有设计流插入和流提取相关的函数,因为 vector 和 string 不同,string 打印时只需要打印字符串即可,但 vector 打印时可能会因为分隔符的原因出现不同的效果,分隔符需要使用者自己去设计,不同的使用者可能会有不同的设计风格,因此就没有提供流插入和流提取相关的函数。

目录

  1. 一、vector 的介绍
  2. 二、vector 的使用
  3. 2.1 构造函数 (constructor)
  4. 2.1.1 默认构造
  5. 2.1.2 使用 n 个 val 进行构造 vector
  6. 2.1.3 使用一段迭代器区间构造 vector
  7. 2.1.4 拷贝构造
  8. 2.1.5 使用数组构造 vector
  9. 2.2 析构函数 (destructor)
  10. 2.3 赋值重载 (operator=)
  11. 2.4 迭代器 (iterator)
  12. 2.4.1 begin
  13. 2.4.2 end
  14. 2.4.3 rbegin
  15. 2.4.4 rend
  16. 2.4.5 迭代器总结
  17. 2.5 容量相关的成员函数 (capacity)
  18. 2.5.1 size
  19. 2.5.2 max_size
  20. 2.5.3 resize
  21. 2.5.4 capacity
  22. 2.5.5 reserve
  23. 2.5.6 reserve 和 resize 的区别
  24. 2.5.7 shrinktofit
  25. 2.6 访问操作相关的成员函数 (element access)
  26. 2.6.1 operator[]
  27. 2.6.2 at
  28. 2.6.3 front
  29. 2.6.4 back
  30. 2.7 修改相关的成员函数 (modifiers)
  31. 2.7.1 assign
  32. 2.7.2 push_back
  33. 2.7.3 pop_back
  34. 2.7.4 insert
  35. 2.7.5 erase
  36. 2.7.6 swap
  37. 2.7.7 clear
  38. 2.8 vector 迭代器失效问题
  39. 2.9 其他

更多推荐文章

查看全部
  • Linux 基础:Shell 概念解析与 Python 环境安装指南
  • 无人机飞行空域申请全流程指南
  • AI Skill 开发实战:网页内容抓取功能实现
  • 前端三剑客:HTML、CSS、JavaScript 如何协同工作
  • Apache IoTDB 数据库管理:增删改查与异构数据库配置
  • 从 Midjourney 到 Runway:AI 视频生成工具进化史
  • 降低 AIGC 检测率的实用技巧
  • 医疗自然语言处理(NLP)实战:从场景到模型落地
  • Python IDLE 使用教程:快速上手自带集成开发环境
  • 前端缓存策略最佳实践:LocalStorage 与 Service Worker
  • 华为 OD 机试真题:挑选宝石 Python & JS 实现
  • AI 小说生成器本地部署与配置教程
  • VSCode Git 工作树自动化管理与高效开发实践
  • SpringBoot 拦截器详解
  • 城市场景下无人机三维路径规划的 NMOPSO 多目标优化算法
  • Python 内存暴涨原因分析及缓存优化与资源回收实践
  • Python 进程池 ProcessPoolExecutor 使用指南
  • Python 鼻炎在线预约挂号评价系统微信小程序设计与开发
  • Docker 部署 PostgreSQL 数据库教程
  • VS Code 中 GitHub Copilot 无法使用的排查与修复方案

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online