以vector为例,我们都知道可以用reserve()和resize()函数来为容器预留空间或者调整它的大小。

不过从它俩的名字上可以看出区别:

reserve():serve是“保留”的词根,所以是用来保留,预留容量的,并不改变容器的有效元素个数。

resize():size是“大小”的意思,它主要用来调整容易有效元素的个数,有时候也会造成容量变大。

先解释两个概念:

容量:即capacity,是指容器在自由内存中获得了多大的存储空间,容量为100并不代表容器就有100个元素,可能容量只有10个,剩下的90个都是闲置的未定义内存空间。

大小:即size,指的是容器中实际元素的个数,大小为100就代表容器有100个已经存在的元素。

好了,下面对reserve()和resize()分别做一个介绍:

1. reserve()

它的函数原型是这样的:

void reserve(size_type n);

对于n值的大小,分两种情况:

(1)如果n大于容器现有的容量(capacity),比如你容器原来是100的容量,我现在指定n=200,那么就需要在自由内存区为整个容器重新分配一块新的更大的连续空间【因为vector是顺序容器,所以存储空间是连续的,如果之前的存储空间不够了,必须这样做】,然后将容器内所有的有效元素从旧位置全部复制到新位置,这个过程是调用拷贝构造函数,然后释放旧位置的所有存储空间,并调整容器的元素位置指示器。所以reserve的时候如果n比原来的大,结果只是让容器的冗余容量(即没有分配元素的存储区)变大,容器的实际大小,即元素个数并没有改变。

(2)如果n小于容器原来的容量,那么这个函数什么作用都没有。相当于白调用了。

2. resize()

它的函数原型是这样的:

void resize(size_type n, const T& c = T());

其中n是要保留的元素个数,如果是要新增元素的话,c则是新增元素的默认初始值。

对于n值的大小,分三种情况:

(1)如果n大于容器当前的大小(即容器的size,这里和capacity无关),则在容器的末尾插入n-size()个初始值为c的元素;如果没有指定初始值,那就元素类型的默认构造函数来初始化。

(2)如果n小于容器当前的大小,则删除末尾的size()-n个元素,这样就导致容器的大小变了,size 变小了。但是这种类型的容器在删除一个元素的时候并不会释放元素本身的内存空间【这也是为了保留这块空间以避免将来要插入新元素的时候又要进行存储空间重分配】,所以容器的容量即capacity其实是没有改变的。

(3)n等于容器当前的大小,则什么也不做。

显然,reserve和resize的共同点就是:都不缩减容器本身的容量。即对内存空间并没有影响。那么要是当你觉得容器的容量太多的时候,应该如何缩减容量呢。这时候需要用到一个利用swap函数的技巧。

STL容器的reserve()函数和resize()函数解析的更多相关文章

  1. 窗体的基类中没有设定大小,所以才不能居中,若要窗体居中,必须使用setfixedsize()函数或者resize()函数设定窗体的大小,居中才能正常使用

    最近开发中,遇到了窗体不能居中的问题,看了网上的很多文章,窗口居中,无非都是move至窗口的中心目标; 有两种方式, 一种在构造函数中直接计算中心坐标; 另一种是在窗口show后再move至相应坐标. ...

  2. c++ stl容器set成员函数介绍及set集合插入,遍历等用法举例

    c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器.set/multiset会根据待定的排序准则,自动将元素排序.两者不同在于前者不允许元素重复,而后者允许. 1 ...

  3. STL容器能力一览表和各个容器操作函数异常保证

    STL容器能力一览表 Vector Deque List Set Multiset map Multimap 典型内部 结构 dynamic array Array of arrays Doubly ...

  4. 如何优雅的传递 stl 容器作为函数参数来实现元素插入和遍历?

    问题背景 开始正文之前,做一些背景铺垫,方便读者了解我的工程需求.我的项目是一个客户端消息分发中心,在连接上消息后台后,后台会不定时的给我推送一些消息,我再将它们转发给本机的其它桌面产品去做显示.后台 ...

  5. OpenCV学习笔记:resize函数改变图像的大小

    OpenCV提供了resize函数来改变图像的大小,函数原型如下: , , int interpolation=INTER_LINEAR ); 参数解释: src:输入,原图像,即待改变大小的图像: ...

  6. STL算法设计理念 - 函数对象和函数对象当参数和返回值

    函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...

  7. C++STL 预定义函数对象和函数适配器

    预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...

  8. opencv2.4.13.7的resize函数使用(c++)

    先来看一下resize函数的原型,如下. C++: void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, doub ...

  9. resize函数有五种插值算法

    转自http://blog.csdn.net/fengbingchun/article/details/17335477 最新版OpenCV2.4.7中,cv::resize函数有五种插值算法:最近邻 ...

随机推荐

  1. centos+apache 2.x 开启gzip压缩

    最近做了一个网站(PHP+Apache+MySQL),挂在百度云平台上面,基本配置是2G内存+5Mb带宽,每次打开主页都需要2-3s左右的时间,对于一个垂直搜索引擎来说,用户体验肯定会很差. 于是开始 ...

  2. Chrome浏览器扩展开发系列之五:Page Action类型的Chrome浏览器扩展

    Page Action类型的Google Chrome浏览器扩展程序,通常也会有一个图标,但这个图标位于Chrome浏览器的地址栏内右端.而且这个图标并非始终出现,而是当某指定的页面打开时才会出现.也 ...

  3. HTML中使用JavaScript的三种方式及优缺点

      1.内部js: 在直接在页面的<script></script>标签内写js代码 优点:相对于使用行内js,内部js代码较为集中,与页面结构的实现代码耦合度较低,比较便于维 ...

  4. springmvc(四) springmvc的数据校验的实现

    so easy~ --WH 一.什么是数据校验? 这个比较好理解,就是用来验证客户输入的数据是否合法,比如客户登录时,用户名不能为空,或者不能超出指定长度等要求,这就叫做数据校验. 数据校验分为客户端 ...

  5. 用 volume container 共享数据 - 每天5分钟玩转 Docker 容器技术(42)

    volume container 是专门为其他容器提供 volume 的容器.它提供的卷可以是 bind mount,也可以是 docker managed volume.下面我们创建一个 volum ...

  6. Docker 部署DropWizard

    FROM index.alauda.cn/alauda/ubuntu MAINTAINER hongxiao.shou "shouhongxiao@163.com" COPY jd ...

  7. JDK+Tomcat+Zookeeper+DubboAdmin安装教程

    JDK+Tomcat+Zookeeper+DubboAdmin安装教程 1. 安装内容: JDK 1.8.131 Tomcat 7.0.77 Zookeeper 3.4.9 Dubbo admin 2 ...

  8. Mac系统下STF的环境搭建和运行

    本文参考以下文章整理:MAC 下 STF 的环境搭建和运行 一. 前言 STF,全称是Smartphone Test Farm,WEB 端批量移动设备管理控制工具,就是可以用浏览器来批量控制你的移动设 ...

  9. Web Service--第一次接触web service

    Web Service 首发于开源中国 1. 背景 中国移动短信网关需求,要能够发送短信.开发材料只有一个短信发送配置:包括ID,password,code,url.一个jar包还有一个老旧的html ...

  10. JavaSE(七)之内部类

    上一篇我们学习了接口还有访问控制,在以后的工作中接口是我们经常要碰到的,所以一定要多去回顾.接下来介绍一下内部类.很多时候我们创建类的对象的时候并不需要使用很多次,每次只使用一次 这个时候我们就可以使 ...