STL容器的reserve()函数和resize()函数解析
以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()函数解析的更多相关文章
- 窗体的基类中没有设定大小,所以才不能居中,若要窗体居中,必须使用setfixedsize()函数或者resize()函数设定窗体的大小,居中才能正常使用
最近开发中,遇到了窗体不能居中的问题,看了网上的很多文章,窗口居中,无非都是move至窗口的中心目标; 有两种方式, 一种在构造函数中直接计算中心坐标; 另一种是在窗口show后再move至相应坐标. ...
- c++ stl容器set成员函数介绍及set集合插入,遍历等用法举例
c++ stl集合set介绍 c++ stl集合(Set)是一种包含已排序对象的关联容器.set/multiset会根据待定的排序准则,自动将元素排序.两者不同在于前者不允许元素重复,而后者允许. 1 ...
- STL容器能力一览表和各个容器操作函数异常保证
STL容器能力一览表 Vector Deque List Set Multiset map Multimap 典型内部 结构 dynamic array Array of arrays Doubly ...
- 如何优雅的传递 stl 容器作为函数参数来实现元素插入和遍历?
问题背景 开始正文之前,做一些背景铺垫,方便读者了解我的工程需求.我的项目是一个客户端消息分发中心,在连接上消息后台后,后台会不定时的给我推送一些消息,我再将它们转发给本机的其它桌面产品去做显示.后台 ...
- OpenCV学习笔记:resize函数改变图像的大小
OpenCV提供了resize函数来改变图像的大小,函数原型如下: , , int interpolation=INTER_LINEAR ); 参数解释: src:输入,原图像,即待改变大小的图像: ...
- STL算法设计理念 - 函数对象和函数对象当参数和返回值
函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...
- C++STL 预定义函数对象和函数适配器
预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...
- opencv2.4.13.7的resize函数使用(c++)
先来看一下resize函数的原型,如下. C++: void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, doub ...
- resize函数有五种插值算法
转自http://blog.csdn.net/fengbingchun/article/details/17335477 最新版OpenCV2.4.7中,cv::resize函数有五种插值算法:最近邻 ...
随机推荐
- angular.extend、angular.$watch、angular.bootstrap
1.angular.extend:依次将第二个参数及后续的参数的第一层属性(不管是简单属性还是对象)拷贝给第一个参数的第一层属性,即如果是对象,则是引用的是同一个对象,并返回第一个参数对象. 直接上代 ...
- usaco training 4.1.1 麦香牛块 题解
Beef McNuggets题解 Hubert Chen Farmer Brown's cows are up in arms, having heard that McDonalds is cons ...
- 算法起步之kmp算法
[作者Idlear 博客:http://blog.csdn.net/idlear/article/details/19555905] 这估计是算法连载文章的最后几篇了,马上就要 ...
- Struts2国际化信息机制
国际化信息机制 (三种 Action范围. Package范围. 全局) 1. 全局国际化配置信息文件 全局国际化文件,对所有Action 生效,任何程序都可以访问到,需要在struts.xml 配 ...
- DataReader To List
用了一段时间的Dapper,感觉Dapper比Ado.net好的地方就是转换成实体,到处查资料,写了以下方法,直接可以用. using (var conn = new SqlConnection(&q ...
- Spring MVC的实现原理
Spring提供了DispatcherServlet,这个类不仅负责实现请求转发,还负责启动一个WebApplicationContext容器. 按照Spring一贯的IoC哲学,所有的Control ...
- Mybatis Dynamic Query 简单筛选
在框架中,筛选描述类有两种(FilterDescriptor, FilterGroupDescriptor),这里我们主要举例来说明FilterDescriptor用法. FilterDescript ...
- [补档][COGS 2434]暗之链锁
[COGS 2434]暗之链锁 题目 传说中的暗之连锁被人们称为Dark.<!--more-->Dark是人类内心的黑暗的产物,古今中外的勇者们都试图打倒它.经过研究,你发现Dark呈现无 ...
- metasploit快速入门
今天没上班,在小黑屋里看了一个一百多页的书<metasploit新手指南>,在此将笔记分享给大家.欢迎大家批评指正,共同学习进步. metasploit新手指南 笔记 kali 0 ...
- 又见angular----步一步做一个angular4小项目
这两天看了看angular4的文档,发现他和angular1.X的差别真的是太大了,官方给出的那个管理英雄的Demo是一个非常好的入门项目,这里给出一个管理个人计划的小项目,从头至尾一步一步讲解如何去 ...