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 使用注意事项的更多相关文章

  1. STL容器vector应用注意事项

    [1]提前分配足够空间以免不必要的重新分配和复制代价 关于vector容器重新分配和复制及析构释放的代价,请参见随笔<STL容器之vector>. 应用示例对比代码如下: #include ...

  2. vector使用注意事项

    1. 需要保存若干同类数据项时,用vector比较方便.不用管理下标,直接push_back即可. 2. 当程序重复执行一段代码时,之前保存数据用的vector需要清空.因为不是按照下标保存的数据,不 ...

  3. C/C++ 随笔目录

    [1]基础部分 (1)宏定义 <assert> <offset宏> <#pragma once> <宏定义学习> <预处理语句> <# ...

  4. C++ vector erase函数的使用注意事项

    最近使用了顺序容器的删除元素操作,特此记录下该函数的注意事项. 在C++primer中对c.erase(p) 这样解释的:  c.erase(p)    删除迭代器p所指向的元素,返回一个指向被删元素 ...

  5. vector的 emplace 和 insert 以及使用vector进行iterator遍历 且 erase的时候注意事项

    vector<int> first;//Size()==2 first.push_back(); first.push_back(); //first.insert(2); vector& ...

  6. 【转】vector中erase()的使用注意事项

    vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase(   iterator _Whe ...

  7. vector注意事项

    vector注意事项: 如果你添加元素,但是vector的容量(是容量,不是大小,容量比大小大,会预先多分配空间)不够的话,系统就会重新分配一段内存,然后把原先的内容全部拷贝过去,然后删除原先的内容. ...

  8. C++中使用vector.erase()需要注意的事项

    本人菜鸟一枚.. 今天在用vector.erase()的时候,发现总是不能把应该erase掉的东西erase干净. 举个栗子: vector<int> num_vec; num_vec.p ...

  9. vector.erase用法注意事项

    转自->这里 vector::erase():从指定容器删除指定位置的元素或某段范围内的元素 vector::erase()方法有两种重载形式 如下: iterator erase(iterat ...

随机推荐

  1. mysql内存分配问题

    云数据库 MySQL 的内存是重要的性能参数,常出现由异常 SQL 请求以及待优化的数据库导致的内存利用率升高的情况,严重时还会出现由于 OOM 导致实例发生 HA 切换,影响业务的稳定及可用性. M ...

  2. Single-shot Object Detection

    以下转自:http://lanbing510.info/2017/08/28/YOLO-SSD.html 在深度学习出现之前,传统的目标检测方法大概分为区域选择(滑窗).特征提取(SIFT.HOG等) ...

  3. A. Even Substrings

    A. Even Substrings time limit per test 0.5 seconds memory limit per test 256 megabytes input standar ...

  4. VMware与Centos系统

    今日任务 1.Linux发行版的选择 2.vmware创建一个虚拟机(centos) 3.安装配置centos7 4.xshell配置连接虚拟机(centos) 选择性 pc可以选择 -纯系统 Lin ...

  5. C++入门经典-例3.19-使用break跳出循环

    1:代码如下: // 3.19.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...

  6. 自定义实现Java动态代理

    转自:https://www.cnblogs.com/rjzheng/p/8750265.html 一 借助JDK的API实现: 1.先创建一个接口,并实现它 public interface Per ...

  7. pom.xml报Plugin execution not covered by lifecycle configuration错误

    环境     eclipse 4.3.0     maven 3.0.4     m2e 1.4.0      出现场景     以前的老项目,在我的环境(我的环境较新)下,别人老环境不报错. 错误示 ...

  8. linux设置MySQL开机自动启动

    step1: 通过chkconfig --list命令查看mysqld是否在列表中: step2: 如果列表中没有mysqld这个,需要先用这个命令添加:chkconfig --add mysqld ...

  9. Gradle 依赖

    在开发中,我们经常使用compile,api,implementation引入库,这三种是有区别的. 1 api和compile api和compile关键字作用效果是一样的,使用时可以互相替换. 实 ...

  10. android 面试汇总<一>

    1.1 Android Activity Q:说下Activity的生命周期? 技术点:Activity生命周期 思路:分条解释Activity从创建到销毁整个生命周期中涉及到的方法及作用 参考回答: ...