STL中的Vector相关用法

  标准库vector类型使用需要的头文件:#include <vector>。

  vector 是一个类模板,不是一种数据类型,vector<int>是一种数据类型。

  Vector的存储空间是连续的,list不是连续存储的。

1. 定义和初始化

vector< typeName > v1;       //默认v1为空,故下面的赋值是错误的v1[0]=5;
//v2是v1的一个副本,若v1.size()>v2.size()则赋值后v2.size()被扩充为 v1.size()。
vector<typeName>v2(v1); 或v2=v1;或vector<typeName> v2(v1.begin(), v1.end());
vector< typeName > v3(n,i);//v3包含n个值为i的typeName类型元素
vector< typeName > v4(n); //v4含有n个值为0的元素
int a[]={,,,,}; vector<int> v5(a,a+);//v5的size为5,v5被初始化为a的5个值。后一个指针要指向将被拷贝的末元素的下一位置。
vector<int> v6(v5);//v6是v5的拷贝
vector< 类型 > 标识符(最大容量,初始所有值);

2. 值初始化

  (1)如果没有指定元素初始化式,标准库自行提供一个初始化值进行值初始化。
  (2)如果保存的式含有构造函数的类类型的元素,标准库使用该类型的构造函数初始化。
  (3)如果保存的式没有构造函数的类类型的元素,标准库产生一个带初始值的对象,使用这个对象进行值初始化。

3. vector对象最重要的几种操作

  (1)v.push_back(t)    在容器的最后添加一个值为t的数据,容器的size变大。

     其中,采用的是复制构造函数重新建立这样的一个对象。  另外list有push_front()函数,在前端插入,后面的元素下标依次增大。
  (2)v.size()        返回容器中数据的个数,size返回相应vector类定义的size_type的值。

     v.resize(2*v.size)或v.resize(2*v.size, 99) 将v的容量翻倍(并把新元素的值初始化为99)
  (3)v.empty()     判断vector是否为空
  (4)v[n]           返回v中位置为n的元素
  (5)v.insert(pointer,number, content)    向v中pointer指向的位置插入number个content的内容。
       还有v. insert(pointer, content),v.insert(pointer,a[2],a[4])将a[2]到a[4]三个元素插入。
  (6) v.pop_back()    删除容器的末元素,并不返回该元素。
  (7)v.erase(pointer1,pointer2) 删除pointer1到pointer2中间(包括pointer1所指)的元素。
        vector中删除一个元素后,此位置以后的元素都需要往前移动一个位置,虽然当前迭代器位置没有自动加1,
     但是由于后续元素的顺次前移,也就相当于迭代器的自动指向下一个位置一样。
  (8)v1==v2          判断v1与v2是否相等。
  (9)!=、<、<=、>、>=      保持这些操作符惯有含义。
  (10)vector<typeName>::iterator p=v1.begin( ); p初始值指向v1的第一个元素。*p取所指向元素的值。
      对于const vector<typeName>只能用vector<typeName>::const_iterator类型的指针访问。
  (11)p=v1.end( ); p指向v1的最后一个元素的下一位置。
  (12)v.clear()      删除容器中的所有元素。但是内存空间不变,只是情况所在内容。

  (13)v.reserve()  初始化预留空间,此动作可以与对象定义分开。

  (14)

3. vector的assign()用法

  vector::assign //用来构造一个vector的函数,类似于copy函数
  void assign( size_type _Count, const Type& _Val);

  注意:

  (1)_Count指要构造的vector成员的个数,   _Val指成员的数值,他的类型必须与vector类型一致!

  (2)这个函数用来,在创建Vector对象后,但是没有对其进行构造容器元素,即将创建对象与构造扩展数据分开。

template<class InputIterator>
void assign( InputIterator _First, InputIterator _Last );
//两个指针,分别指向复制开始和结束的地方!
EXAMPLE
// vector_assign.cpp
// compile with: /EHsc
#include <vector>
#include <iostream> int main( )
{
using namespace std;
vector<int> v1, v2, v3;
vector<int>::iterator iter; v1.push_back();
v1.push_back();
v1.push_back();
v1.push_back();
v1.push_back(); cout << "v1 = " ;
for (iter = v1.begin(); iter != v1.end(); iter++)
cout << *iter << " ";
cout << endl; v2.assign(v1.begin(), v1.end());
cout << "v2 = ";
for (iter = v2.begin(); iter != v2.end(); iter++)
cout << *iter << " ";
cout << endl; v3.assign(, ) ;
cout << "v3 = ";
for (iter = v3.begin(); iter != v3.end(); iter++)
cout << *iter << " ";
cout << endl;
}

  输出:

v1 =
v2 =
v3 =

  size()成员指当前拥有的元素个数;capacity()成员指当前(容器必须分配新存储空间之前)可以存储的元素个数。reserve()成员可以用来控制容器的预留空间。vector另外一个特性在于它的内存空间会自增长,每当vector容器不得不分配新的存储空间时,会以加倍当前容量的分配策略实现重新分配。例如,当前capacity为50,当添加第51个元素时,预留空间不够用了,vector容器会重新分配大小为100的内存空间,作为新连续存储的位置。

  在调用push_back时,每次执行push_back操作,相当于底层的数组判定是否需要重新分配大小;,然后将原来的元素拷贝到新的存储,之后在拷贝push_back的元素,最后要析构原有 的vector并释放原有的内存。例如下面程序:

#include <iostream>
#include <cstdlib>
#include <vector> using namespace std; class Point
{
public:
Point()
{
cout << "construction" << endl;
}
Point(const Point& p)
{
cout << "copy construction" << endl;
}
~Point()
{
cout << "destruction" << endl;
}
}; int main()
{
vector<Point> pointVec;
Point a;
Point b;
pointVec.push_back(a);
pointVec.push_back(b); cout<<pointVec.size()<<std::endl; return 0;
}

  程序输出:

  

4. vector的内存释放

  由于vector的内存占用空间只增不减,比如你首先分配了10,000个字节,然后 erase掉后面9,999个,留下一个有效元素,但是内存占用仍为10,000个。所有内存空间是在vector析构时候才能被系统回收。 empty()用来检测容器是否为空的,clear()可以清空所有元素。但是即使clear(),vector所占用的内存空间依然如故,无法保证内存 的回收。

 (1)  如果需要空间动态缩小,可以考虑使用deque。如果非vector不可,可以用swap()来帮助你释放内存。具体方法如下:

vector<int> nums;
nums.push_back(1);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2);
vector<int>().swap(nums); //或者nums.swap(vector<int> ())

  或者如下所示,使用一对大括号,意思一样的:

//加一对大括号是可以让tmp退出{}的时候自动析构
{
std::vector<int> tmp = nums;
nums.swap(tmp);
}

   swap()是交换函数,使vector离开其自身的作用域,从而强制释放vector所占的内存空间,总而言之,释放vector内存最简单的方法是 vector<int>.swap(nums)。

  (2)但是如果nums是一个类的成员,不能把 vector<int>.swap(nums)写进类的析构函数中,否则会导致double free or corruption (fasttop)的错误,原因可能是重复释放内存。标准解决方法如下:

template < class T >
void ClearVector( vector< T >& vt )
{
vector< T > vtTemp;
veTemp.swap( vt );
}

  (3) 如果Vector中存放的是指针

  如果vector中存放的是指针,那么当vector销毁时,这些指针指向的对象不会被销毁,那么内存就不会被释放。如下面这种情况,vector中的元素时由new操作动态申请出来的对象指针:

#include <vector>
using namespace std; vector<void *> v;

  每次new之后调用v.push_back()该指针,在程序退出或者根据需要,用以下代码进行内存的释放:

for (vector<void *>::iterator it = v.begin(); it != v.end(); it ++)
if (NULL != *it)
{
delete *it;
*it = NULL;
}
v.clear();

官方说明:   http://www.cplusplus.com/reference/vector/vector/assign/

 

STL中的Vector相关用法的更多相关文章

  1. C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET

    C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...

  2. Java中Date各种相关用法

    Java中Date各种相关用法(一) 1.计算某一月份的最大天数 Java代码 Calendar time=Calendar.getInstance(); time.clear(); time.set ...

  3. 转:用STL中的vector动态开辟二维数组

    用STL中的vector动态开辟二维数组 源代码:#include <iostream>#include <vector>using namespace std;int mai ...

  4. (转)C++ STL中的vector的内存分配与释放

    C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...

  5. C++STL中的vector的简单实用

    [原创] 使用C++STL中的vector, #include <stdio.h> #include<stdlib.h> #include<vector> usin ...

  6. STL中的vector实现邻接表

    /* STL中的vector实现邻接表 2014-4-2 08:28:45 */ #include <iostream> #include <vector> #include  ...

  7. C++ STL中的 Set的用法

    https://blog.csdn.net/yas12345678/article/details/52601454 -----源头此处 1.关于set的概念   set   是STL中的集合. 集合 ...

  8. [转] C++ STL中map.erase(it++)用法原理解析

    总结一下map::erase的正确用法. 首先看一下在循环中使用vector::erase时我习惯的用法: for(vector<int>::iterator it = vecInt.be ...

  9. Binary Search 的递归与迭代实现及STL中的搜索相关内容

    与排序算法不同,搜索算法是比较统一的,常用的搜索除hash外仅有两种,包括不需要排序的线性搜索和需要排序的binary search. 首先介绍一下binary search,其原理很直接,不断地选取 ...

随机推荐

  1. 【343】MathJax、LaTex、Mathml 数学公式

    参考:cnblog中添加数学公式支持 分类参考: 1. 基本功能 MathJax 我的LaTeX入门 MathJax basic tutorial and quick reference 分段函数:矩 ...

  2. PowerDesigner表生成 EXCEL

    今天收到一个需求,要把数据库设计给一个excel版本的,百度出来一个脚本文件,很好用发现,留个纪念 在pd中,shift+ctrl+X,打开脚本运行,脚本如下,附件也留了一份: '********** ...

  3. KNN识别手写数字

    一.问题描述 手写数字被存储在EXCEL表格中,行表示一个数字的标签和该数字的像素值,有多少行就有多少个样本. 一共42000个样本 二.KNN KNN最邻近规则,主要应用领域是对未知事物的识别,即判 ...

  4. python集合的交,差,并,补集合运算汇总

    集合操作实际用的不多,了解即可. 交集:          ( & 或者 intersection ) 并集:    ( | 或者 union ) 差集:   ( -  或者  differe ...

  5. airway之workflow

    1)airway简介 在该workflow中,所用的数据集来自RNA-seq,气道平滑肌细胞(airway  smooth muscle cells )用氟美松(糖皮质激素,抗炎药)处理.例如,哮喘患 ...

  6. linux的文件类型和权限

    Linux下使用ll或ls -l查看文件的信息 (ll和ls-l的区别:ll会显示出当前目录下的隐藏文件,而ls -l不会)   文件信息分为:文件类型.权限.链接数.所属用户.所属用户组.文件大小. ...

  7. Cannot resolve class or package 'dbcp' Cannot resolve class 'BasicDataSource'

    在applicationContext.xml中配置数据源时,报错如下: Cannot resolve class or package 'dbcp' Cannot resolve class 'Ba ...

  8. Alberta family's QR code is world's largest corn maze

    BY DARREN WEIR     SEP 10, 2012 IN ODD NEWS Link:http://www.digitaljournal.com/article/332512   Laco ...

  9. codeblocks 更换颜色主题

    关闭codeblocks,下载主题文件(colour_themes.conf).在关闭codeblocks的情况下,linux下的~/.config/codeblocks/下有个conf文件,将其备份 ...

  10. 中文路径读取乱码,json乱码

    strPath = 'E:\新建文件夹' #含有中文的路径,使用unicode函数转换. strPath = unicode(strPath , "utf8") 参考:http:/ ...