STL:string 大小(Size)和容量(Capacity)
strings存在三种“大小”:
1、size()和length()
返回string中现在的字符个数。上述两个函数等效。
成员函数empty()用来检验字符数是否为0,亦即字符串是否为空。你应该优先使用该函数,因为它比length()或size()来得快。
也就是说,使用if(s.empty() == true)而不使用if(s.size() == 0)(笔者注)
2、max_size()
此函数返回一个string最多能够包含的字符数。一个string通常包含一块单独内存区块内的所有字符,所以可能跟PC机器本省的限制有关系。返回值一般而言是索引型别的最大值减1。之所以“减1”有两个原因:(a)最大值本身是npos;(b)在具体实现中,可因此轻易在内部缓冲区之后添加一个'\0',以便将这个string当做C-string使用(例如透过c_str())。一旦某个操作函数使用一个长度大于max_size()的string,length_error异常就会被抛出来。
3、capacity()
重新分配内存之前,string所能包含的最大字符数。
让string拥有足够的容量是很重要的,原因有二:
1、重新分配会造成所有指向string的references,pointer和iterators失效。
2、重新分配(reallocation)很耗时间。
因此,如果程序要用到指向string(或其内部字符)的references,pointers和iterators。抑或需要很快的执行速度,就必须考虑容量(capacity)问题。成员函数reserve()就是用来避免重分配行为。reserve()使你得以预留一定容量,并确保该容量尚有余裕之时,reference能够一直保持有效:
std::string s; // create empty string
s.reserve(80); // reserve memory for 80 characters
容量概念应用于string和应用于vector是相同的,但有一个显著差异:面对string你可以调用reserve()来缩减实际容量,而vector的reserve()却没有这项功能。拿一个“小于现有容量”的参数来调用reserve(),实际上就是一种非强制性请求(nonbinding shrink request)——如果参数小于现有字符数,则这项请求被视为非强制性适度缩减请求(nonbinding shrink-to-fit-requset)。也就是说你可能想要缩减容量至某个目标,但不保证你一定可以如愿。String的reserve()参数做默认值为0,所以调用reserve()并且不给参数,就是一种“非强制性适度缩减请求”:
s.reserve(); // "would like to shrink capacity to fit the current size"
为什么缩减动作是非强制性的呢?因为"如何获取最佳性能"系由实现者定义。具体实作string时,如何处理速度和内存耗用量之间关系可能有不同的设计思路。因此任何实作作品都可以以较大的魄力增加容量,并且永不缩减。
C++Standard规定,唯有在相应reserve()调用时,容量才可能缩减。因此即使发生 "字符被删除或被改变"的事情,任何其他字符只要位于“被操作字符”之前,指向他们身上的那些references、pointer和iterator就仍然保持有效。
备注:本文内容摘自《C++标准程序库》(侯捷 孟岩译)
STL:string 大小(Size)和容量(Capacity)的更多相关文章
- C# 调用存储过程出错:String[3]: Size 属性具有无效大小值 0
存储过程如下 Create PROCEDURE [dbo].[Test] @FundId int, @vchStrategyToken nvarchar(), @ErrorMessage nvarch ...
- EF执行存储工程报错 String[4]: Size 属性具有无效大小值 0。
EF中执行存储过程报错 String[4]: Size 属性具有无效大小值 0 排查后是如下问题所致,给定的参数没有设定大小(加入红框内的就可以了) private string GetCode(MC ...
- 深入剖析 linux GCC 4.4 的 STL string
转自: 深入剖析 linux GCC 4.4 的 STL string 本文通过研究STL源码来剖析C++中标准模板块库std::string运行机理,重点研究了其中的引用计数和Copy-On-Wri ...
- C++ STL——string和vector
目录 一 STL基本概念 二 string容器 三 vector容器 3.1 vector动态增长原理 3.2 vector构造函数 3.3 vector常用赋值操作 3.4 vector大小操作 3 ...
- C++ STL string
要想使用标准C++中string类,必须要包含 #include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 ...
- stl string常用函数
string类的构造函数: string(const char *s); //用c字符串s初始化 string(int n,char c); //用n个字符c初始化 此外,string类还支持默认构造 ...
- STL string 常用函数(转)
string类的构造函数: string(const char *s); //用c字符串s初始化 string(int n,char c); //用n个字符c初始化 此外,string类还支持默认构造 ...
- Warning: Call to 'toArray()' with pre-sized array argument 'new String[list.size()]'
当使用如下代码将List转换为Array类型时: List<String> list = new ArrayList<>(); String[] array = list.to ...
- 转C++之stl::string写时拷贝导致的问题
前几天在开发某些数据结构到文件的 Dump 和 Load 功能的时候, 遇到的一个 bug . [问题复现] 问题主要出在 Load 过程中,从文件读取数据的时候, 直接使用 fread 的去操作 s ...
随机推荐
- Matlab实现抽样定理
Matlab实现抽样定理 正弦信号的抽样: 首先时间跨度选择 -0.2 到 0.2,间隔0.0005取一个点,原信号取 sin(2π*60t) ,则频率为60Hz. 由于需要输出原始信号的波形,我选 ...
- iOS10推送必看UNNotificationServiceExtension
转:http://www.cocoachina.com/ios/20161017/17769.html (收录供个人学习用) iOS10推送UNNotificationServic 招聘信息: 产品经 ...
- < java.util >-- Iterator接口
每一个集合都有自己的数据结构,都有特定的取出自己内部元素的方式.为了便于操作所有的容器,取出元素.将容器内部的取出方式按照一个统一的规则向外提供,这个规则就是Iterator接口. 也就说,只要通过该 ...
- Lua利用cjson读写json示例分享
本文结合本人的实际使用经验和代码示例,介绍如何在Lua中对json进行encode和decode,需要的朋友可以参考下 我这里采用的是Lua CJson库,是一个高性能的JSON解析器和编码器,其性能 ...
- 引擎设计跟踪(九.9) 文件包系统(Game Package System)
很早之前,闪现过写文件包系统的想法, 但是觉得还没有到时候. 由于目前工作上在做android ndk开发, 所以业余时间趁热做了android的移植, 因为android ndk提供的mountab ...
- CNAME
CNAME指别名记录也被称为规范名字.这种记录允许您将多个名字映射到同一台计算机. 通常用于同时提供WWW和MAIL服务的计算机.例如,有一台计算机名为“host.mydomain.com”(A记录) ...
- Android 中多点触摸协议
http://blog.csdn.net/zuosifengli/article/details/7398661 Android 中多点触摸协议: 参考: http://www.kernel.org/ ...
- 改写Form的submit
表单的一些应用常识: 1.在用户第一次提交完表单后应防止用户不耐烦而多次点击submit按钮,需要在onsubmit事件中制止用户的重复行为. 2.不要简单粗暴的用reset()重置表单,如果用户不想 ...
- delphi快捷键
分类 快捷键 解释 备注 组 件 设 计 类 Escape 选择当前组件容器 Shift + Click 选择多个组件:选择窗体 Tab 选择下一个组件 Shift + Tab ...
- POJ 2674
Linear world Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 2448 Accepted: 564 Descr ...