string::reserve和string::size疑点分析

C++(03):string的length, size, capacity, resize, reserve 主要注意的是扩容后,string对象会分配新的内存空间,然后将原来的字符串拷贝到新的空间,并释放原有的空间,也就是说:字符串的内容还维持不变,但是保存字符串的空间可能已经发生了变化。当count的数量大于当前的size时,string对象保存的字符串长度会增长,如果传递了ch参数,则使用ch的字符来填充,如果没有指定ch,则使用'\0'进行填充。如果new_cap的值大于当前string对象的容量,则对string的容量进行扩容,扩容后的容量大于等于new_cap。可以看到字符串没有受到影响。 阅读详情

对于C++的vector容器模板类,存在size和capacity这样两个概念,可以分别通过vector的size()和capacity()方法获得该vector当前的size和capacity值。相应的,vector提供了两个方法来分别对size和capacity进行操作,它们就是resize方法和reserve方法。

 

首先,对于size和capacity,这是两个比较容易混淆的概念。都说要抱着问题来学习,才能做到事半功倍。那么,这里便提出三个问题:什么是vector的大小(即size)?什么是vector的容量(即capacity)?这两个概念的区别在哪里?

 

对于抽象的问题,只要我们把它们同我们的生活实际相结合,将问题具象化,自然就会很好的理解。

就拿我们的办公室举例,假设,我们部门的办公地点位于公司大楼的六楼。在我们的办公室里面,放置了100套办公桌椅(工位),公司说按照一个萝卜一个坑来算,你们部门最多只能招这么多人,那么,这时我们可以说,我们部门的容量(即capacity)就是100人,如果我们部门是公司刚成立的部门,正处于发展壮大的阶段,目前只有40为员工,也就是说,办公室里只坐了40个人,另外60个工位是空着的,那么,我们可以说,我们部门当前的大小(即size)是40人。这实际上就是size和capacity的区别。类比到vector,size和capacity的概念自然就很清楚了。

 

cplusplus.com中对capacity是这样定义的:

This capacity is not necessarily equal to the vector size. It can be equal or greater, with the extra space allowing to accommodate for growth without the need to reallocate on each insertion.

一个allowing道出了真谛!这里还要区分两个概念,就是:为vector分配的存储空间和vector的大小是两个不同的概念。为vector分配的存储空间,实际上就是capacity,指的是当前vector最多能使用的存储空间,是大于等于vector的大小的,当vector实际需要使用的存储空间大于当前分配给它的存储空间时,需要重新为其分配存储空间。

 

cplusplus.com中对size的定义是:

This is the number of actual objects held in the vector, which is not necessarily equal to its storage capacity.

实际上就是vector中当前实际存储的元素个数。

 

弄清楚了size和capacity这两个概念之后,对于resize和reserve两个方法就很好理解了。

cplusplus.com中对reserve的定义是:

 

Request a change in capacity

Requests that the vector capacity be at least enough to contain n elements.

If n is greater than the current vector capacity, the function causes the container to reallocate its storage increasing itscapacity to n (or greater).

In all other cases, the function call does not cause a reallocation and the vector capacity is not affected.

This function has no effect on the vector size and cannot alter its elements.

 

 

从上面的说明中,可以得到以下信息:

1、reserve方法被用来重新分配vector的容量大小;

2、只有当所申请的容量大小n大于vector的当前容量时,才会重新为vector分配存储空间;

3、reserve方法对于vector的大小(即size)没有任何影响;

 

具体通过下面的例子验证

#include <iostream>

#include <vector>


using namespace std;


int main()

{

vector<int> vect;


vect.reserve(5); // 调用reserve方法为vect分配容量(即存储空间)


vect.push_back(1);

vect.push_back(2);

vect.push_back(3);

vect.push_back(4); // 插入4个元素


cout << vect.size() << endl; // vect的实际大小(即包含多少元素)

cout << vect.capacity() << endl; // vect的容量大小


return 0;

}


结果为

 

从结果中,就可以很清楚的看到capacity和size的区别。

 

下面看一个综合的例子,可以从中获得很多信息:

#include <iostream>

#include <vector>


using namespace std;


int main()

{

vector<int> vect;


vect.reserve(5);


vect.push_back(1);

vect.push_back(2);

vect.push_back(3);

vect.push_back(4);


cout << vect.size() << endl;

cout << vect.capacity() << endl;


vect.push_back(5);

vect.push_back(6); // 插入两个元素,此时vect的大小大于之前分配的容量5


cout << "size1 = " << vect.size() << endl;

cout << "capacity1 = " << vect.capacity() << endl;


vect.push_back(7);

vect.push_back(8); // 在插入两个元素,和上面的结果进行对比,会有意外收获

cout << "size1_1 = " << vect.size() << endl;

cout << "capacity1_1 = " << vect.capacity() << endl;


vect.reserve(3); // 当程序执行到此处时,vect的容量大小一定是大于3的


cout << "size2 = " << vect.size() << endl;

cout << "capacity2 = " << vect.capacity() << endl;


vect.reserve(12);


cout << "size3 = " << vect.size() << endl;

cout << "capacity3 = " << vect.capacity() << endl;


return 0;

}
执行结果为:

 

对这一执行结果,一点点进行分析:

1、首先,看结果size1和capacity1,在打印这两个结果前,程序向vect中插入了两个元素,之前,vect中存在4个元素且容量为5,按照我之前的设想,如果我采用push_back向vect中插入元素时,当元素数量大小capacity时,vect的capacity会随着size变大而变大,但应该是和size相等。但此处,vect的大小为6,但是容量却是7,且这个7,来的很是突然,我往哪个方面靠都靠不上啊。好吧,先把这个疑问姑且放下,现在我们猜想,是不是push_back中针对这种情况会有处理,始终保持vect的capacity比size至少大1,带着这个猜想继续向下看,我又向vect中插入了两个元素,此时,vect的大小为8,若是我们刚才的猜想是正确的话,则此时,vect的capacity应该增大为9了,但是此时结果size1_1和capacity1_1却给了我当头一棒,这个10又是怎么回事?学习编程永远记住一件事情,所有问题的答案,都能从代码中找到。于是,我顺着vector的push_back源码开始找下去,就有了下面这段追踪代码

void push_back(_Ty&& _Val)

...

if (this->_Mylast == this->_Myend)

_Reserve(1);

...


void _Reserve(size_type _Count)

{ // ensure room for _Count new elements, grow exponentially

size_type _Size = size();

if (max_size() - _Count < _Size)

_Xlen();

else if ((_Size += _Count) <= capacity())

;

else

reserve(_Grow_to(_Size));

}


size_type _Grow_to(size_type _Count) const

{ // grow by 50% or at least to _Count

size_type _Capacity = capacity();


_Capacity = max_size() - _Capacity / 2 < _Capacity

? 0 : _Capacity + _Capacity / 2; // try to grow by 50%

if (_Capacity < _Count)

_Capacity = _Count;

return (_Capacity);

}

由这段官方实现代码,终于找到了答案,原来在使用push_back向vect中插入元素时,如果当前元素数量大于vector的capacity时,会重新为vector分配存储空间,而分配的原则就是:

                    原capacity + 原capacity / 2

这样,就解释了上面的7和10两个结果,最初,vect的容量大小为5,在第一次插入两个元素后,vector中的元素数量大于5了,所以此时,会重新为vect分配容量,分配大小为5 + 5 / 2 = 7,而同样的,第二次重新分配vect的容量是7 + 7 / 2 = 10,这就合理的解决了刚才的疑问。

 

2、当vect的容量大小为10时,再调用reserve方法,重新为其设置容量为3时,不会进行任何操作,可以看到,vect的容量大小还是10;

3、当为vect设置容量大小为12时,可以看到,成功的改变了vect的容量大小;

4、不论哪次调用reserve方法,vect的size大小在调用前后,始终没有被改变过。

 

到此,是我对reserve方法的一些思考和验证。

原文转载自:https://blog.youkuaiyun.com/vampirem_chosen_one/article/details/50519870

【PLL】分频器设计权衡:从CMOS到CML的电路实现与优化 本文深入探讨了PLL中分频器的设计权衡,比较了CMOS和CML两种电路实现的优缺点。通过实际案例分析,展示了如何在速度、功耗和噪声之间取得平衡,特别是在5G射频芯片和Wi-Fi 6E等高频应用中的优化实践。文章还提供了混合架构设计和电源噪声协同优化的实用技巧,适合电路设计工程师参考。 阅读详情

相关推荐

图形引擎实战:镭射效果制作分享

该方案的优势1.遵循物理的2.可以使用少量的参数去调控镭射的效果。计算相对简单,缺点仍是颜色不能够自定义,还有一种常见的方案是采样一张镭射贴图来模拟,好处是颜色可以自定义同时性能上还很高效没有复杂的公式计算。我查阅了网上普遍的方案,常见的做法是制作一个Ramp图生成工具,然后将生成好的ramp图赋给材质。这两个方案的好处是美术同学可以手动的去控制镭射的颜色。最后就是Shader中对Ramp图的采样的部分,Ramp图的UV坐标是使用fresnel作为Ramp的U轴坐标,0.5作为V轴坐标。

qq_41166022的博客 1359

string类:`reserve()`,`resize()`详解

PS:reserve(size_t n) 为string预留空间,不改变有效元素个数;当 reserve 的参数小于底层空间总大小时,reserve 不会改变容量大小。n > capacity ——> 扩容+尾插 size < n < capacity ——> 尾插 n < size ——> 删除数据,只保留前 n 个 ​PS:resize() 在改变元素个数时,如果是将元素个数增加,可能会改变 capacity 的大小—— 、 这两种情况;如果是将元素个数减少,则不改变 capacity 的大小—— 的

taduanlangan的博客 1117

STM32F103RC学习(一)

STM32F103RC学习(一)

Cat_South_North的博客 6058

C++——string(2)

在上一篇博客中,我们讲解了string里面一部分指令的用法,类似计算长度,计算最大长度等等。那么今天我们就继续对其深入了解string的其他指令吧。

dongxue727504的博客 1062

单细胞测序流程(八)单细胞的marker基因转化和​GO富集分析

系列文章目录 单细胞测序流程(一)简介与数据下载 单细胞测序流程(二)数据整理 单细胞测序流程(三)质控和数据过滤——Seurat包分析,小提琴图和基因离差散点图 单细胞测序流程(四)主成分分析——PCA 单细胞测序流程(五)t-sne聚类分析和寻找marker基因 单细胞测序流程(六)单细胞的细胞类型的注释 单细胞测序流程(七)单细胞的细胞类型轨迹分析———————————————— 本期主讲内容——单细胞的maeker基因转化和​富集分析 marker基因转化是为了将基因的id和基.

qq_45478665的博客 1万+

用Plecs搞定半桥LLC谐振变换器仿真:从开环模型搭建到闭环PI调参全流程

本文详细介绍了使用Plecs仿真工具进行半桥LLC谐振变换器从开环模型搭建到闭环PI调参的全流程操作。涵盖仿真环境准备、关键元件参数计算、波形异常排查、闭环控制实现及PI参数整定等核心内容,特别针对仿真中的收敛性问题提供实用解决方案,助力电力电子设计者高效完成LLC变换器仿真验证。

weixin_28455801的博客 571

std::string reserve详解

详解当然是从源码入手了. 我们先来看看string的reserve的源码 template<typename _CharT, typename _Traits, typename _Alloc> void basic_string<_CharT, _Traits, _Alloc>:: reserve(size_type __res) { ...

李兆龙的博客 2940

vue微前端qiankun框架学习到项目实战,基座登录动态菜单及权限控制

技术无关,独立开发,独立部署,增量升级,独立运行,微前端的核心目标是将巨石应用拆解成若干可以自治的松耦合微应用。

前端开发工程师 9751

C++学习笔记(14)——string的库函数reserve、resize

学习reserve和resize的原理

broken_enginer的博客 3917

草莓成熟度与叶片病虫害智能检测数据集应用全解析

本文深入解析草莓成熟度与叶片病虫害智能检测数据集的应用价值,涵盖从绿草莓到红果转色的完整成熟周期及白粉病、炭疽病等7种病害的精准识别。通过实战案例展示如何提升病害识别率至94%,并介绍数据集的科研价值,包括跨品种迁移学习和多模态数据融合技术。

weixin_28366353的博客 275

RK3568平台(KBuild篇)KBuild编译体系

从Linux内核2.6开始,Linux内核的编译采用Kbuild系统,这和过去的编译系统有很大的不同,尤其对于Linux内核模块的编译。在新的系统下,Linux编译系统会两次扫描Linux的Makefile:首先编译系统会读取Linux内核顶层的Makefile,然后根据读到的内容第二次读取Kbuild的Makefile来编译Linux内核。kbuild,即 kernel build,用于编译 Linux 内核文件。

weixin_49303682的博客 349

C++ String(2)

需要注意的是, std::to_string 是 C++11 标准引入的函数,如果你使用的是较老的编译器,可能需要检查是否支持该函数。返回一个新的字符串,表示原始字符串从 pos 位置开始,长度为 len 的子字符串。如果不提供, std::string::npos 将被用作默认值,意味着子字符串将从 pos 开始一直延伸到原字符串的末尾。assign函数的功能就是将原有的字符串覆盖掉它可以支持一些赋值操作符无法做到的事,因为赋值操作符是双目操作符,只能有两参数,但是assign可以有多个参数。

Starry_tsx的博客 1417

教你写出高质量SQL(实践必备)

1、查询SQL尽量不要使用select * ,而是select具体字段。 //反例子 select * from sys_user; //正例子 select id,name from sys_user; 理由: 只取需要的字段,节省资源、减少网络开销;select * 进行查询时,很可能就不会使用到覆盖索引,就会造成回表查询; 覆盖索引:只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表,速度更快。 例如: 回表查询:先通过普通索引的值定位聚簇索引值,再通过聚簇索引的值定位行记..

ANGEL CITY 9996

std::string的resize()与reserve()的区别

std::string的resize()与reserve()的区别: resize():改变的是size()与capacity()的大小 (1)、比原来的变小之后,后面的会被截断 (2)、比原来的变大之后,后面的会被填充新的东西,不同的编译器可能会不同 reserve():改变的只是capacity()的大小 程序如下: #include <math.h> #includ...

一缕阳光的博客 4189

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【C++String类成员函数辨析】resize(),size(),capacity(),reserve()函数的解析与对比

朋友们好,这篇播客我们继续C++的初阶学习,现在对我们对C++的string类中的几个内存空间函数做出总结对比,整理出来一篇博客供我们一起复习和学习,如果文章中有理解不当的地方,还希望朋友们在评论区指出,我们相互学习,共同进步!这几个函数相对来说还是很好理解,我们就不对其再做具体介绍,看一段代码即懂! ⚠️代码示例: ⭐️:结果输出 代码解释:size和length函数的功能都是计算字符串大小,capacity函数计算为字符串分配的内存空间。尽管我们调用clear()函数清空了字符串内容,但是其容量依然不变

qq_43727529的博客 3340

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

C++中vector/string的capacity、size、resize、reserve和clear功能详解

size() – 返回目前存在的元素数。即: 元素个数 capacity() – 返回容器能存储 数据的个数。 即:容器容量 reserve() --设置 capacity 大小 resize() --设置 size ,重新指定有效元素的个数 ,区别与reserve()指定 容量的大小 capacity 一般大于size的原因是为了避免 每次增加数据时都要重新分配内存,所以一般会 生成一个较大的空间,以便随后的数据插入。 size是当前vector容器真实占用的大小,也就是容器当前拥有多少个容器。 c

DayDayUp 2776

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

std::vector中resize()和reserve()区别

在STL容器中vector用的还是比较多的,但是在使用时,会对resize()和reserve()的使用产生迷惑,现在就对这一情况做个对比: resize():改变的是size()与capacity()的大小 (1)、比原来的变小之后,后面的会被截断 (2)、比原来的变大之后,后面的会被填充新的东西,不同的编译器可能会不同。也可以自己指定后面填充的内容 reserve():改变的只是...

一缕阳光的博客 6798

C++基础---string类的capacity/max_size/size/length/empty/reserve/resize

1. string中capacity/max_size/size/length/empty/reserve/resize 1.1 std::string::capacity 原型: size_t capacity() const; 说明: 返回string分配的存储容量。 1.2 std::string::max_size 原型: size_t max_size() const; 说明: 返回string对象中

Catherine的笔记 4333

C++ string类(reserve,resize,insert,erase,at,replace...)

本文详细介绍了C++中string类的常用操作及其底层原理。主要内容包括:size()和length()的功能一致性;size与capacity的区别,前者表示实际字符数,后者代表内存容量;reserve()用于预分配空间提升效率;clear()清空内容但不释放内存;shrink_to_fit()释放多余内存;resize()调整字符串大小;insert()的各种插入操作及其效率问题;erase()的多种删除方式及其时间复杂度。这些操作涉及字符串的内存管理、扩容机制和性能优化,是高效使用string类的基础

2401_88465894的博客 1159

string之size/capacity/reserve/resize/clear/empty/max_size/shring_of_fit函数

对string的capacity和size的操作函数 size()函数和length()函数的结果相同,都是返回字符串有效字符的长度,都不包含最后的’\0’,底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致。 capacity函数返回当前string的预留空间的大小。 max_size()输出一个字符串最多有多长,输出为定值,在Win32的编译环境下是42亿九千万多,即...

weixin_41249411的博客 563

reserve和resize的认知与区别

reserve:预留内存空间,不改变容器的大小。resize:改变容器的实际元素数量。

2301_80171129的博客 1447

c++string类的成员函数: max_size、capacity、reserve、resize、find、substr、分离一个网址的协议,域名,?等、clear、insert、empty等的介绍

c++string类的成员函数: max_size、capacity、reserve、resize、find、substr、分离一个网址的协议,域名,?等、clear、insert、empty、erase、replace、swap、c_str、compare、npos、getline等的介绍c++string类的成员函数: max_size、capacity、reserve、resize、find、substr、分离一个网址的协议,域名,?

Farewell_me的博客 925

C++之std::string的resize与reverse

在C++中我们经常用std::string 来保存字符串,其中有两个比较常用但是却平时容易被搞混的两个函数,分别是resize和reserve,模糊意识里,这两个方法都是对std::string的容量或元素进行操作,那么这两个函数到底做了什么呢?先声明string中的两个概念,capaticy(容量)和size(大小)

Milu_Jingyu的博客 2235

string模拟实现reserve

扩容这里是可以实现缩容,可以实现扩容,这里主要实现的就是扩容的实现,这里实现缩容的实现。

Jason_from_China的博客 436

string中的 reserve()和 resize()

 reserve() 为容器预留足够的空间,避免不必要的重复分配。预留空间大于等于字符串的长度。预留空间可以通过capacity()查看。  resize() 调整字符串的大小。如果字符串长度变小,多余的字符会被截掉。若长度变大,可以设置填充的字符。长度可以通过size()查看。 1. reserve() string str = "April"; str.reserve(20);   ...

万里归来少年心 1万+

C++中string的Reserve() 和 capacity()

reserve 原型: #include  void reserve( size_type size = 0 ); 函数reserve()将字符串的容量设置为至少size. 如果size指定的数值要小于当前字符串中的字符数(亦即size ), 容量将被设置为可以恰好容纳字符的数值. reserve()以线性时间(linear time)运行. resize

Nancy_m的专栏 1万+
上一篇: 图像中的基本概念
下一篇: C++中查找字符或者字符串的一些函数
LiBin1103
博客等级 码龄9年 38粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值