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++标准程序库》(侯捷 孟岩译)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器