std::string在 Windows MSVC和Linux Gcc 中capacity容量扩容策略的分析和对比

news2025/2/4 8:01:56

1、capacity()作用

       在std::string中,capacity()为当前string占用内存字符的长度,表示当前string的容量,可以理解为一个预分配制度,如果当前的string不断进行扩展操作,则不需要每次都进行内存上的分配,提高程序的运行效率。所以capacity的值会大于等于size,而不是代表当前string的实际大小。

2、Gcc分配策略

        查看Gcc关于string的capacity的代码,大致如下:

分配通过_M_mutate实现,_M_mutate再调用_M_create,调用实际的分配策略。

_M_mutate():

_M_create():

_M_max_size()如下:

       可以看到,当所要扩容后的capacity如果大于_M_max_size,会抛出异常。这里不展开关注,只需要关注在正常可以扩容的情况下的capacity的变化。如果所要扩容后的capacity大于老的capacity,则进行二倍的的扩展。这就是Gcc的分配策略。

3、MSVC分配策略

MSVC通过_Calculate_growth()完成capacity的扩容处理。代码如下:

        _ALLOC_MASK,为15,这个值是在编译期确定的值

        每次capacity分配都会将需要将string的请求长度_Requested与_Alloc_Mask进行或运算,得到一个_Requested加上一个<=15的值_Masked如果该值大于_Max,则最大分配为_Max,不会像Gcc先抛出异常。

        然后将该值与旧值大小的1/2增长进行比较,取两者的较大的值为新的capacity。

4、代码验证

        测试思路,先定义一个空的string,查看初始的capacity值,然后做10次扩容测试,查看每次扩容后的capacity情况。

测试代码如下:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    std::string str;
    std::cout<<"origin capacity: "<<str.capacity() << " size: "<<str.size()<<std::endl;
    for (int i = 0; i < 10; i++)
    {
        auto cap = str.capacity();
        while(str.size() <= cap)
        {
            str.append("1");
        }
        std::cout<<"capacity: "<<str.capacity() << " size: "<<str.size()<<std::endl;
    }
    return 0;
}

4.1 Windows下capacity变化情况

        可以看出,一个空的string的capacity初始值系统分配为15,然后再扩容后,后面每次capacity的大小为size/2 + size

4.2 Linux下capacity变化情况

Linux下为一个空的string分配的初始capacity也是15,后面每次进行扩容,都是当前(size/2)*2。

5、横向比对Gcc和MSVC的分配策略

        MSVC的扩容要小于Gcc下的扩容大小,这决定了在Linux下string进行不断进行增大时,效率要优于Windows,分配的频率会小于Windows。但是Linux下分配会占用的内存大于Windwos环境,这也可以理解,因为Linux本身运行的程序多为企业级多并发的大程序,利用Linux高资源的特点,可以用空间换时间,获得更快的运行效率。而Windows下运行的多为单机程序,运行的程序不像Linux环境下那么庞大,也不需要极致的空间置换时间,且Wndows的系统资源比较有限,这样可以在保证程序高效运行的情况下,兼顾系统资源在多程序之间的合理分配。

6、capacity扩容后的元素内存地址的变化

        我们vector内部的内存结构也是一块连续的内存,当容量进行扩展后,需要重新分配内存,然后进行内容的迁移,string是不是也是如此,进行代码验证。

        每次都监视首个元素的地址,当元素插入超过15时,看是否发生首个元素地址的变化。

        测试代码如下:

        

int main()
{
    string str; 
	for (int index = 0; index < 20; ++index)
	{
		str.push_back('1');
		std::cout << "size: " << str.size() << " capacity: " << str.capacity() << " str address: " << &str << " data address: " << (const void*)(&str[0]) << endl; 
    }
    return 0;
}

测试结果如下:

可以看到扩容后首个元素的内存地址也是发生了变化,和vector一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1337424.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS7搭建Elasticsearch与Kibana服务

1.部署单点es 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kibana容器互联。这里先创建一个网络&#xff1a; docker network create es-net 1.2拉取elasticsearch镜像 docker pull elasticsearch:7.11.1 1.3.运行 运行docker命令&#xff0c;部…

NLP论文阅读记录 - 以大语言模型为参考学习总结

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作2.1文本生成模型的训练方法2.2 基于LLM的自动评估2.3 LLM 蒸馏和基于 LLM 的数据增强 三.本文方法3.1 Summarize as Large Language Models3.1.1 前提3.1.2 大型语言模型作为参考具有…

面向对象设计与分析40讲(15)简单工厂方法模式

文章目录 定义示例优缺点定义 简单工厂模式是一种创建型模式,用于根据客户端的需求创建对象实例,所谓的需求反映到编程语言里就是传入的参数。 简单工厂模式包括三个主要部分: 工厂类(Simple Factory):这是整个模式的核心。它负责根据客户端的请求来创建并返回相应的对…

罗门哈斯同级抛光树脂:单晶硅电池超纯水生产与应用

在光伏行业中&#xff0c;单晶硅电池是最高效和最可靠的太阳能电池之一。然而&#xff0c;生产单晶硅电池需要使用超纯水&#xff0c;这是许多光伏制造商所面临的一个挑战。那么&#xff0c;超纯水是如何生产的呢&#xff1f; 为什么需要超纯水&#xff1f; 超纯水是一种高纯…

vue3 setup + ts 项目模块找不到问题解决:Cannot find module ...

Vscode contrl shift p 打开vscode配置面板&#xff0c;查找typescript&#xff1b;是使用workspace version,完事儿

EternalBlue【永恒之蓝】漏洞详解(复现、演示、远程、后门、入侵、防御)内容丰富-深入剖析漏洞原理-漏洞成因-以及报错解决方法-值得收藏!

漏洞背景&#xff1a; 1.何为永恒之蓝&#xff1f; 永恒之蓝&#xff08;Eternal Blue&#xff09;爆发于2017年4月14日晚&#xff0c;是一种利用Windows系统的SMB协议漏洞来获取系统的最高权限&#xff0c;以此来控制被入侵的计算机。甚至于2017年5月12日&#xff0c; 不法分子…

JavaScript基础练习题解析与实践

如果大家感感兴趣也可以去看&#xff1a; &#x1f389;博客主页&#xff1a;阿猫的故乡 &#x1f389;系列专栏&#xff1a;JavaScript专题栏 &#x1f389;ajax专栏&#xff1a;ajax知识点 &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 学习…

HarmonyOS4.0系统性深入开发04UIAbility组件详解(下)

UIAbility组件间交互&#xff08;设备内&#xff09; UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时&#xff0c;会涉及到启动特定的UIAbility&#xff0c;该UIAbility可以是应用内的其他UIAbility&#xff0c;也可以是其他应用的UIAbility&#xff08;例如启…

LSTM的记忆能力实验 [HBU]

目录 模型构建 LSTM层 模型训练 多组训练 模型评价 模型在不同长度的数据集上的准确率变化图 模型汇总 总结 长短期记忆网络&#xff08;Long Short-Term Memory Network&#xff0c;LSTM&#xff09;是一种可以有效缓解长程依赖问题的循环神经网络&#xff0e;LSTM 的…

Text-to-SQL小白入门(十)RLHF在Text2SQL领域的探索实践

本文内容主要基于以下开源项目探索实践&#xff0c; Awesome-Text2SQL:GitHub - eosphoros-ai/Awesome-Text2SQL: Curated tutorials and resources for Large Language Models, Text2SQL, Text2DSL、Text2API、Text2Vis and more.DB-GPT-Hub&#xff1a;GitHub - eosphoros-ai…

【QML-按钮】

QML编程指南 VX&#xff1a;hao541022348 ■ 按钮■ AbstractButton■ Button■ CheckBox■ DelayButton■ RadioButton■ RoundButton&#x1f31f;■ Switch&#x1f31f;■ ToolButton&#x1f31f; ■ 按钮 ■ AbstractButton 所有的按钮控件的父类都是 AbstractButton 。…

Electron自定义通知Notification

Notification是什么&#xff1f; 对于渲染进程&#xff0c;Electron 允许开发者使用通知中API&#xff0c;来运行系统的原生通知进行显示。 如何实现系统Notification&#xff1f; const { Notification } require(electron);const isAllowed Notification.isSupported();…

市场复盘总结 20231226

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整 昨日回顾&#xff1a; SELECT CODE,成交额排名,净流入排名,代码,名称,DDE大单金额,涨幅,主力净额,DDE大单净量,CONVERT(DATETIME, 最后封…

概率论1:下象棋问题(3.5)

每日小语 时刻望着他人的眼色行事&#xff0c;是腾飞不了的。自己怎么想就积极地去做&#xff0c;这是需要胆量的。——广中平佑 题目 甲、乙二人下象棋&#xff0c; 每局甲胜的概率为a,乙胜的概率为b. 为简化问题&#xff0c;设没有和局的情况&#xff0c;这意味着a b1. 设想…

Flappy Bird游戏python完整源码

通过pygame实现当年风靡一时的flappy bird小游戏。 当前只设定了同样长度的管道&#xff0c;图片和声音文件自行导入。 效果如下&#xff1a; # -*- coding:utf-8 -*- """ 通过pygame实现曾风靡一时的flappybird游戏。 小鸟x坐标不变&#xff0c;画布左移实现…

分享5款对工作有帮助的小工具

​ 在职场中&#xff0c;简单而高效的工具是我们事业成功的一部分。这五款工具可能会成为你职业生涯中的得力助手。 1.图片标注——iPhotoDraw ​ iPhotoDraw是一款图片标注软件&#xff0c;可以在图片上添加文字、符号、尺寸、放大细节等注释对象&#xff0c;增加图片的信息…

〖Python网络爬虫实战㊹〗- JavaScript Hook 的用法

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;订阅本专栏前必读关于专栏〖Python网络爬虫实战〗转为付费专栏的订阅说明作者&#xff1…

SQL server 数据库练习题及答案(练习2)

使用你的名字创建一个数据库 创建表&#xff1a; 数据库中有三张表&#xff0c;分别为student,course,SC&#xff08;即学生表&#xff0c;课程表&#xff0c;选课表&#xff09; 问题&#xff1a; --1.分别查询学生表和学生修课表中的全部数据。--2.查询成绩在70到80分之间…

文件操作(c)

1.文件分类&#xff1a;分为程序文件和数据文件 1.程序文件&#xff1a;源程序文件&#xff08;后缀.c&#xff09;,目标文件&#xff08;windows环境后缀.obj&#xff09;,可执行程序&#xff08;windows环境后缀.exe&#xff09; 2.数据文件&#xff1a;程序运行时读写的数据…

【MySQL】复合查询 | 内外连接

文章目录 一、MySQL复合查询基本查询回顾多表查询自连接子查询单行子查询多行子查询多列子查询在from子句中使用子查询合并查询 二、MySQL内外连接内连接外连接左外连接右外连接 一、MySQL复合查询 基本查询回顾 准备测试表 下面给出三张表&#xff0c;员工表&#xff08;emp&…