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. Javascript 函数传参问题

    属于传值,不能改变参数的属性 example 1  function Myvalue(){ var arry = 5; return arry ; } document.getElementById( ...

  2. fiddler无法抓取chrome解决方法

    前端开发中,不可避免的要和服务器端进行联调,少了fiddler这个利器可不行. 由于无线开发需要配置UA,我使用chrome进行访问,但是今儿一早过来,发现fiddler无法抓取chrome的请求了. ...

  3. dp-最长公共子序列

    最长公共子序列(NYOJ36) 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 咱们就不拐弯抹角了,如题,需要你做的就是写一个程序,得出最长公共子序列.tip:最长公 ...

  4. 首届阿里巴巴在线技术峰会,9位大V演讲整理!

    https://yq.aliyun.com/articles/57826 感谢参加阿里巴巴在线技术峰会.7月19日的3场专家分享:Blink.Docker.电商互动:7月20日的云数据库十大经典案 例 ...

  5. cloudrea manager 调整datanode数据存储目录

    由于datanode所需磁盘空间较大,所以工作中可能会涉及到给datanode增加磁盘目录或者更改数据目录 CM停止该datanode节点 CM页面增加目录或者修改目录 如果是修改目录的话 需要将服务 ...

  6. django MongoDB上传文件

    django上传文件,查询到的资料都是用的django自己的models.Model类,去定义一个FileField类型的存储文件,并且在里面加一句upload_to,如下所示:   但是如果用mon ...

  7. Maven项目整合Struts2框架

    -------------------------siwuxie095                                 Maven 项目整合 Struts2 框架         1. ...

  8. Nmap参数说明

    Nmap(Network Mapper)是一款开放源代码的网络探测和安全审核工具.它的设计目标是快速地扫描大型网络,不适应于单一主机.Nmap使用检测IP数据包来确定访问的主机.提供的服务.数据包的类 ...

  9. 读书笔记---改善c#编程的157个建议

    1.在拼接string时,如果牵涉到其他类型,先tostring一下会减少装箱操作:频繁操作字符串变量的话,使用stringbuilder效率较高. 2.tryParse相对于parse而言效率高,t ...

  10. Codeforces 677C. Coloring Trees dp

    C. Coloring Trees time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...