1、vector中push_back操作

push_back的作用是在vector的末尾添加一个新元素。val的内容被复制(或移动)到新元素。

这有效地将容器大小增加1。当且仅当新的vector大小超过当前vector容量时,会重新自动分配新的存储空间。

Tips:

  • std::vector::size()

    vec.size()返回vec中元素的个数。
  • std::vector::capacity()

    vec.capacity()返回vec在内存中分配的空间大小。

push_back操作demo1:

//code1

#include <iostream>
#include <vector>
using namespace std; #define MAX_NUM 9 int main(){
vector<int> vecInt; for(int i = 0; i != MAX_NUM; i++){
vecInt.push_back(i);
}
/**
some code
*/
vecInt.push_back(123); for(int i : vecInt){
cout << i << " ";
} return 0;
}
// 0 1 2 3 4 5 6 7 8 123

以上代码先声明了一个存放int类型的vector,然后把i递增push_back到vecInt中。之后再添加一个元素到123到vecInt中。

push_back操作demo2:

iterator遍历vector

//code2

#include <iostream>
#include <vector>
using namespace std; #define MAX_NUM 9 int main(){
vector<int> vecInt; for(int i = 0; i != MAX_NUM; i++){
vecInt.push_back(i);
} vector<int>::iterator iter = vecInt.begin();
cout << "the 1st element: " << *iter << endl; vecInt.push_back(123); while(iter != vecInt.end()){
cout << *iter << " ";
iter++;
} return 0;
}
/*
the 1st element: 0
0 1 2 3 4 5 6 7 8 123
*/

在用for进行vector的push_back之后,初始化了一个iterator指向vecInt的begin位置,并打印验证。之后再用push_back在vector的末尾添加一个元素123,这时再用iter来遍历vecInt。

push_back操作demo3:

下面对MAX_NUM进行修改,将其改为8

//code3
#include <iostream>
#include <vector>
using namespace std; #define MAX_NUM 8 //MAX_NUM修改为8,其余地方不做任何修改 int main(){
vector<int> vecInt; for(int i = 0; i != MAX_NUM; i++){
vecInt.push_back(i);
} vector<int>::iterator iter = vecInt.begin();
cout << "the 1st element: " << *iter << endl; vecInt.push_back(123);
cout <<"vecInt's capacity: " << vecInt.capacity() << endl; while(iter != vecInt.end()){
cout << *iter << " ";
iter++;
} return 0;
}
/*
the 1st element: 0
vecInt's capacity: 16
-17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -17891602 -784369068 805499525 0 1 2 3 4 5
6 7 123
*/

只修改了MAX_NUM的值,其他一致。再次运行程序时,程序异常。

原因分析

对于vector来说,和数组最大的区别之一就是不需要在初始化的时候声明vector的大小。如果初始化的时候没有指明vector的大小,那么会根据实际的使用情况,在内存中为vector分配的大小分别2->4->8->16...

当MAX_NUM是8时,在for循环进行push_back之后,vecInt在内存中的大小为8。对vecInt再次将123进行push_back的时候,新的vector大小将超过当前的vector大小,所以会自动重新分配存储空间。

由于vector的存储空间已经被重新分配,在push_back123之后iter自然也就指向一个未知的空间,所以程序异常。

2、 vector的reserve的作用

为避免vector中在push_back过程中会进行内存的自动重新分配问题,vector提供了reserve函数。

reserve的作用时更改vector的容量,使vector至少可以容纳n个元素。

如果n大于vector当前的容量,reserve会对vector进行扩容,且当push_back的元素数量大于n的时候,会重新分配一个大小为2n的新空间,再将原有的n的元素放入新开辟的内存空间中。其他情况下都不会重新分配vector的存储空间。

Demo:对比使用reserve的区别

说明:在main中声明了两个vector,vecInt为默认初始化,vecIntB使用capacity初始化其容量为100。分别对vetIntA和vecIntB进行同样的操作:

①把0~99依次push_back到vector中,

②在push_back的过程中观察vector的容量capacity是否发生变化。

#include <iostream>
#include <vector>
#include <stdint.h>
using namespace std; void growPushBack(vector<int> &vec, uint16_t size){
for(int i = 0; i < 100; i++){
vec.push_back(i);
if(size != vec.capacity()){
size = vec.capacity();
cout << "Capacity changed: " << size << endl;
}
}
}
int main(){
uint16_t sz = 0;
vector<int> vecIntA;
sz = vecIntA.capacity();
//声明vector后未使用reserve,直接进行push_back操作
cout << "Making vecIntA growing:" << endl;
growPushBack(vecIntA, sz); cout << "\n========separator========\n" << endl; vector<int> vecIntB;
sz = vecIntB.capacity();
//声明vecIntB后用reserve来执行其容量为100
vecIntB.reserve(100);
cout << "Making vecIntB growing: " << endl;
growPushBack(vecIntB, sz); return 0;
}
/*
Making vecIntA growing:
Capacity changed: 1
Capacity changed: 2
Capacity changed: 4
Capacity changed: 8
Capacity changed: 16
Capacity changed: 32
Capacity changed: 64
Capacity changed: 128 ========separator======== Making vecIntB growing:
Capacity changed: 100
*/

Demo运行结果分析:

如果一个vector使用默认的capacity,那么在push_back操作的时候,会根据添加元素的数量,动态的自动分配空间,2^n递增;如果声明vector的时候,显式的使用capacity(size_type n)来指定vector的容量,那么在push_back的过程中(元素数量不超过n),vector不会自动分配空间。

C++ vector.reserve方法作用的更多相关文章

  1. vector 内部方法大全 学习(初学者的参考资料)

    1    vector构造函数:也就是如何对一个vector对象进行初始化 ////////////////////////////代码//////////////////////////////// ...

  2. Struts2中的get、set方法作用:

    Struts2中的get.set方法作用: 在Struts2中,客户端和服务器之间的数据传输全部要用到get.set方法:用set方法 ,可以将表单中的值存入Action类.通过Struts2.0标签 ...

  3. HTTP的options方法作用

    1.HTTP的options方法作用 检测服务器所支持的请求方法.(比如:‘/user'路由支持哪些方法:get.post.delete...) CORS中的预检请求(检测某个接口是否支持跨域) 2. ...

  4. C++Vector使用方法

    C++内置的数组支持容器的机制,可是它不支持容器抽象的语义.要解决此问题我们自己实现这种类.在标准C++中,用容器向量(vector)实现.容器向量也是一个类模板.标准库vector类型使用须要的头文 ...

  5. STL vector使用方法介绍

    介绍 这篇文章的目的是为了介绍std::vector,怎样恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用.通 ...

  6. vector reserve与resize区别

    vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize改变了vector的capacity同时也增加了它的size!原因如下:reserve是容器 ...

  7. vector.resize 与 vector.reserve的区别 .xml

    pre{ line-height:1; color:#9f1d66; background-color:#a0ffc0; font-size:16px;}.sysFunc{color:#5d57ff; ...

  8. java中的hashcode方法作用以及内存泄漏问题

    本文装载:http://hi.baidu.com/iduany/item/6d66dfc9d5f2da1650505870 hashCode()方法的作用&使用分析 一直以来都想写篇文章来说明 ...

  9. vector.resize 与 vector.reserve的区别(转载)

    转载:https://blog.csdn.net/shuilan0066/article/details/3588478 reserve是容器预留空间,但并不真正创建元素对象,在创建对象之前,不能引用 ...

  10. Springmvc的拦截器执行顺序及各方法作用

    实现HandlerInterceptor接口或者继承HandlerInterceptor的子类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInt ...

随机推荐

  1. 数栈V6.0全新产品矩阵发布,数据底座 EasyMR 焕新升级

    4月20日,袋鼠云成功举行了以"数实融合,韧性生长"为主题的2023春季生长大会.会上,袋鼠云自主研发的一站式大数据基础软件--数栈V6.0产品矩阵全新发布.对旗下大数据基础平台. ...

  2. FastAPI日志审计:你的权限系统是否真的安全无虞?

    title: FastAPI日志审计:你的权限系统是否真的安全无虞? date: 2025/06/20 16:21:09 updated: 2025/06/20 16:21:09 author: cm ...

  3. Blazor学习之旅(4)数据共享

    本篇,我们来了解下在Blazor中数据是如何共享的,组件之间又该如何传递参数. 关于Blazor组件 在 Blazor 中,从名为"组件"的自包含代码部分生成 UI.每个组件都可以 ...

  4. node调用powershell脚本

    前提 .bat 是 Windows 批处理脚本文件的扩展名,用于编写和执行一系列 Windows 命令. .ps1才是是 PowerShell 脚本文件的扩展名,用于编写和执行 PowerShell ...

  5. windows使用chrome调试ios webView

    包含safari和App如果安装失败,直接删除C:\Users\Administrator\scoop 重新安装即可 安装scoop windows下的安装源搜索工具,有点类似centos下的yum. ...

  6. Luogu P3549 [POI 2013] MUL-Multidrink 题解

    P3549 [POI 2013] MUL-Multidrink 非常 tricky 的一道题,模拟赛拼尽全力无法战胜,写篇题解记录一下. 容易理解的直接构造法. 按原题限制随便跳会破坏很多性质,几乎无 ...

  7. in 笔试题目 前端总结 abc类地址 转载

    什么是A类.B类.C类地址? http://www.cnblogs.com/li-hao/archive/2012/04/06/2434563.html B类地址第1字节和第2字节为网络地址,其它2个 ...

  8. 用C++标准库的方式使用堆

    简介 RT 参考链接 https://github.com/lishaohsuai/digital_geo/blob/master/Surface_Framework_VS2017/SurfaceMe ...

  9. 【原创工具】简单实现云控Win电脑锁屏

    手机云控 Windows 电脑锁屏 背景 在工作时,常会遇到这么一个场景:坐在电脑前办公,突然被叫了出去,可能出去只有一两分钟或几分钟,因此我不会将电脑锁屏,同时由于常用电脑做一些前台任务,电脑也不设 ...

  10. POLIR-Organization-Gov.: 国家网信办 和 公安部 的 "人脸识别技术应用安全管理办法"

    人脸识别技术应用安全管理办法 2025年03月21日 17:00,来源:中国网信网 国家互联网信息办公室 中华人民共和国公安部 令 第19号 <人脸识别技术应用安全管理办法>已经2024年 ...