c++ vector 使用注意事项
1. 初始化
c++ 11以后新增了大括号{}的初始化方式,需要注意与()的区别,如:
std::vector<int> vecTest1(5); //初始化5个元素,每个都是0
std::vector<int> vecTest2{ 5 }; //初始化1个元素,值是5
2. 添加元素:push_back
通过push_back添加新的元素进入vector后,vector的内存有时候会发生变化,这取决于size和capacity大小,当然这些都是系统来处理的,详细可以参考stl源码
当size<capacity的时候,直接加到末尾,不会变化
当size==capacity的时候,会重新申请另外一块内存,然后copy过去加到尾部,这个时候就会有变化了。
对于stl的容器,都有成员:
begin() //起始位置
end() //结束位置
size() //当前大小
capacity() //当前容量,即已申请的内存大小
vector是一段连续的内存空间,有三个标识内存的位置,start,end,finish, size=end-start, capacity=finish-start
很多时候在使用vector的时候,会看到size=capacity,这个时候直接添加元素到尾部,内存明显是不够的,此时会重新在别处分配一块大小足够
有时候也有size<capacity, 这个时候就直接加在尾部了。
std::cout << "vecNum push back init" << std::endl;
vector<int> vecNum(5);
std::cout << "vecNum addr: " << &vecNum << std::endl;
for(auto i = 5; i < 10; i++)
{
vecNum.push_back(i*10);
std::cout << "vecNum push_back(" << i << ")=" << i*10 << std::endl; std::cout << "vecNum.size() = " << vecNum.size() << ",vecNum.capacity() = " << vecNum.capacity() << std::endl;
std::cout << "vecNum.begin() addr: " << &(*vecNum.begin()) << std::endl;
}
std::cout << "vecNum addr: " << &vecNum << std::endl;
3. 关于earse和remove
erase返回的是当前删除的元素的一下个位置的迭代器,所以需要注意的是遍历时候的++运算,这个与其它list,map差不多,
需要注意的earse后内存并未真正的清空,仅仅是删除内容,真正的容量大小capacity并没有改变,需要通过swap来实现capacity的减小
全部清空可以考虑:vector<int>().swap(vecNum);
auto itor = vecNum.begin();
for( ; itor != vecNum.end(); )
{
auto num = *itor;
if(num == )
{
itor = vecNum.erase(itor);
break;
}
else
{
itor++;
}
}
std::cout << "after erase element 60:" << std::endl;
printVector(vecNum);
vector<int>(vecNum).swap(vecNum); //将vecNum的内存空洞清除
printVector(vecNum);
//remove只是通过迭代器的指针向前移动来删除,将不需要删除的元素往前移,因此需要删除的就都在尾部了
//返回新的指向尾部需要删除的元素的迭代器
因此还是得配合earse来使用,所以一般真要删除,建议直接遍历使用earse
auto itor = remove_if(vecNum.begin(), vecNum.end(),[](int x)->bool{ return x == ; });
//or
//auto itor = remove(vecNum.begin(), vecNum.end(),20); //通过erase删除
vecNum.erase(itor, vecNum.end());
4. 关于vector< bool> -- 慎用
出处: https://blog.csdn.net/DoronLee/article/details/78462208
vector< bool> 并不是一个STL容器,不是一个STL容器,不是一个STL容器!
首先vector< bool> 并不是一个通常意义上的vector容器,这个源自于历史遗留问题。
早在C++98的时候,就有vector< bool>这个类型了,但是因为当时为了考虑到节省空间的想法,所以vector< bool>里面不是一个Byte一个Byte储存的,它是一个bit一个bit储存的!
因为C++没有直接去给一个bit来操作,
所以用operator[]的时候, 正常容器返回的应该是一个对应元素的引用,
但是对于vector< bool>实际上访问的是一个”proxy reference”而不是一个”true reference”,返回的是”std::vector< bool>:reference”类型的对象。
因此,使用auto自动类型推导时会出现问题
//vector<bool>慎用
vector<bool> vecBool = { false, true, false };
bool test1 = vecBool[0];
auto test2 = vecBool[1];
test1 = true; //test1的初始化它其实暗含了一个隐式的类型转换(直接对vecBool[0]赋值会修改vecBool中的值,但是对test1不会)
test2 = false; //test2它的类型并不是bool,而是一个vector< bool>中的一个内部类,而此时如果修改test2的值,vecBool中的值也会跟着修改
auto index = 0;
for (auto i : vecBool)
{
cout << "vecBool[" << index << "]" << i << std::endl;
index++;
}
c++ vector 使用注意事项的更多相关文章
- STL容器vector应用注意事项
[1]提前分配足够空间以免不必要的重新分配和复制代价 关于vector容器重新分配和复制及析构释放的代价,请参见随笔<STL容器之vector>. 应用示例对比代码如下: #include ...
- vector使用注意事项
1. 需要保存若干同类数据项时,用vector比较方便.不用管理下标,直接push_back即可. 2. 当程序重复执行一段代码时,之前保存数据用的vector需要清空.因为不是按照下标保存的数据,不 ...
- C/C++ 随笔目录
[1]基础部分 (1)宏定义 <assert> <offset宏> <#pragma once> <宏定义学习> <预处理语句> <# ...
- C++ vector erase函数的使用注意事项
最近使用了顺序容器的删除元素操作,特此记录下该函数的注意事项. 在C++primer中对c.erase(p) 这样解释的: c.erase(p) 删除迭代器p所指向的元素,返回一个指向被删元素 ...
- vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项
vector<int> first;//Size()==2 first.push_back(); first.push_back(); //first.insert(2); vector& ...
- 【转】vector中erase()的使用注意事项
vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase( iterator _Whe ...
- vector注意事项
vector注意事项: 如果你添加元素,但是vector的容量(是容量,不是大小,容量比大小大,会预先多分配空间)不够的话,系统就会重新分配一段内存,然后把原先的内容全部拷贝过去,然后删除原先的内容. ...
- C++中使用vector.erase()需要注意的事项
本人菜鸟一枚.. 今天在用vector.erase()的时候,发现总是不能把应该erase掉的东西erase干净. 举个栗子: vector<int> num_vec; num_vec.p ...
- vector.erase用法注意事项
转自->这里 vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase(iterat ...
随机推荐
- 2018 计蒜之道 初赛 第五场 A 贝壳找房搬家
贝壳找房换了一个全新的办公室,每位员工的物品都已经通过搬家公司打包成了箱子,搬进了新的办公室了,所有的箱子堆放在一间屋子里(这里所有的箱子都是相同的正方体),我们可以把这堆箱子看成一个 x*y*z 的 ...
- CF 354 D 迷宫与门的旋转 BFS +状态压缩 一定要回头看看
D. Theseus and labyrinth time limit per test 3 seconds memory limit per test 256 megabytes input sta ...
- Springboot 注册拦截器
拦截器 创建myInterceptor类 import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSer ...
- 【Red Hat Linux基础】 磁盘分区详细教程
https://blog.51cto.com/sunjie123/1687535 Linux中添加新硬盘后对硬盘的分区以及挂载 https://www.linuxidc.com/Linux/2018- ...
- [LOJ3106][TJOI2019]唱、跳、rap和篮球:DP+生成函数+NTT+容斥原理
分析 令\(f(i)\)表示共\(i\)组同学讨论cxk的位置的方案数(不考虑其他位置上的人的爱好),这个数组可以很容易地通过依次考虑每个位置是否是四个人中最后一个人的位置来递推求解,时间复杂度\(O ...
- AcWing:110. 防晒(贪心)
有C头奶牛进行日光浴,第i头奶牛需要minSPF[i]到maxSPF[i]单位强度之间的阳光. 每头奶牛在日光浴前必须涂防晒霜,防晒霜有L种,涂上第i种之后,身体接收到的阳光强度就会稳定为SPF[i] ...
- JS框架_(JQuery.js)圆形多选菜单选项
百度云盘 传送门 密码:zb1c 圆形多选菜单选项效果: <!DOCTYPE html> <html lang="en" > <head> &l ...
- plt.plot() 无法使用参数ax
问题参考 TypeError: inner() got multiple values for keyword argument 'ax' fig, ax=plt.subplots(2,1) plt. ...
- 剑指offer32----之字形打印一颗二叉树
题目 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推. 思路 在这里我们如果单纯的使用队列去弄的话,会很 ...
- webpack 最新版
之前说过老的版本,webpack@3.8.1 这个版本,现在我们来看看,新版本和老版本的区别 webpack 4 以上的版本 npm 全称 node package manager (node 包管理 ...