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 ...
随机推荐
- python 正则表达式实例:
#!/usr/bin/python import re line = "Cats are smarter than dogs" matchObj = re.match( r'(.* ...
- Linux—查看路由
下面那些命令可以用来查看Linux主机的默认路由() A.route B.ifconfig C.ping D.netstat 分析: A.route命令用来显示目前本机路由表的内容,并且还可以针对路由 ...
- 【IOI2018】组合动作
还是自己水平不够,想了两天没想出来--(然后我就被其他人吊打了) 这种题目看了题解就秒会,自己想就想不出来-- 下面是我的心路历程(我就在想出来又叉掉的不断循环中度过--) 开始把题目看成了查询限制 ...
- LibreOJ NOI Round #2 Day 1
LibreOJ NOI Round #2 Day 1 T1: 别被定义弄晕了 反着做,A->1/A+B 取倒数没法做,所以变成a/b,维护2*2的矩阵 区间?不用线段树,不用倍增 存在逆矩阵,直 ...
- C++入门经典-关于extern变量
1:extern用于解决使用非本源文件的全局变量. 例如:在sample1.cpp中 int a,b; /*外部变来那个定义*/ char c; void main() { cout<<a ...
- 使用Desktop App Converter打包桌面应用程序
打包具有安装程序 (.msi) 的应用程序 DesktopAppConverter.exe -Installer C:\Installer\MyAppSetup.msi -Destination C: ...
- Spark学习(二)——RDD的设计与运行原理
Spark的核心是建立在统一的抽象RDD之上,使得Spark的各个组件可以无缝进行集成,在同一个应用程序中完成大数据计算任务.RDD的设计理念源自AMP实验室发表的论文<Resilient Di ...
- EBS 页面影藏“关于此页”
EBS环境: R12.1.3 问题:要影藏EBS登录页面左下角的“关于此页” 方法: 修改的配置文件参数:FND:诊断 , 由 是 改为 否 个性化自助定义 ,由 是 改为 否参数说明:‘FND:诊断 ...
- Spring配置多个数据源,并实现数据源的动态切换转载)
1.首先在config.properties文件中配置两个数据库连接的基本数据.这个省略了 2.在spring配置文件中配置这两个数据源: 数据源1 <!-- initialSize初始化时建立 ...
- T78748 【lcez模拟赛】机场Ⅰ
T78748 [lcez模拟赛]机场Ⅰ 其实这就是最小生成树的题辣 注意输入毒瘤 输入的话要避免记录中间这个‘ , ’ 如下操作可以解决 特别注意%d之间的‘ , ’ 边的权值要现算 存点的话存横纵坐 ...