C++的动态数组vector番外之capacity

news2024/11/15 3:56:38

今日诗词:

爱他明月好,憔悴也相关。

西风多少恨,吹不散眉弯。

                                        ——《临江仙·寒柳》【清】纳兰容若


目录

引言

正文

string中的和vector中的capacity有什么区别

 vector扩容时内存分配的策略是什么?

capacity在vector中的表现如何

解析:

下期预告:C++容器之字符串的详解


引言:

看标题就知道我们今天要说的是capacity。其实我们之前在讲关于C++的(动态,静态)二维数组的补充那一章就提到过capacity,只不过当时是string的capacity,今天说的是vector中的capacity。那么两者的关系是增么样的,以及capacity的扩容规则是什么,还有就是在vector数组中的体现是什么,请看正文。

正文

string中的和vector中的capacity有什么区别

vector中的capacity和string中的capacity在概念上有相似之处,但也存在一些差异,主要体现在它们各自所属的数据结构和用途上。
1.共同点
容量定义:两者都表示容器在不重新分配内存的情况下能够存储的最大元素数量。即,capacity是容器预留的空间大小,用于存储元素,但并非所有预留的空间都已被实际使用。
获取方式:通过各自的成员函数capacity()来获取当前的容量值。
差异点
2.数据结构:
vector是C++标准模板库(STL)中的一个序列容器,用于存储元素的集合,这些元素可以是任意类型,并支持随机访问。
string同样是STL中的一个容器,但它专门用于存储字符序列,通常用于处理文本数据。在内部实现上,string可以被视为一种特殊的vector<char>,但它在操作字符序列时提供了更多的便利性和安全性。
3.扩容行为:
当vector的当前大小(size)等于其容量(capacity)时,如果继续添加新元素,vector会自动扩容,通常是通过分配一个更大的内存块并将旧元素复制到新块中来实现的。扩容的具体策略(如增长因子)可能因编译器和标准库实现而异。
string的扩容行为与vector类似,但在处理字符序列时可能有一些特定的优化。例如,某些string实现可能会使用短字符串优化(SSO),即对于较短的字符串,直接使用对象内部的存储空间来避免动态内存分配。
4.用途和特性:
vector因其灵活性和随机访问能力而被广泛用于需要动态数组的场景。
string则专门用于处理文本数据,提供了丰富的字符串操作函数,如拼接、查找、替换等,这些操作在vector中可能不那么直观或高效。
5.总结:
vector中的capacity和string中的capacity都表示容器预留的空间大小,用于存储元素。它们在概念上是相似的,但在具体的数据结构、扩容行为和用途上存在差异。vector更侧重于提供一个灵活的动态数组,而string则专注于高效地处理文本数据。string类中的capacity


 vector扩容时内存分配的策略是什么?

vector扩容时内存分配的策略主要是基于其当前容量(capacity)和元素数量(size)来决定的,具体策略可能因不同的编译器和标准库实现而有所不同,但通常遵循以下原则:

1.增长因子:

当vector的当前容量不足以容纳新元素时,它会重新分配一块更大的内存空间。这块新空间的大小通常是原容量的一个倍数,这个倍数就是所谓的增长因子。常见的增长因子是2,意味着新容量通常是原容量的两倍。但也有其他可能的增长因子,如1.5倍,这取决于具体的实现和操作系统。

2.内存分配:

vector会分配一块足够大的新内存块,其大小至少能容纳当前所有元素加上即将添加的新元素。这块新内存块的大小由增长因子和当前容量共同决定。

3.元素复制/移动:

在分配了新的内存块之后,vector会将原内存块中的所有元素复制到新内存块中。这个复制过程可能通过元素的拷贝构造函数或移动构造函数来完成,具体取决于元素的类型和编译器的优化。

4.内存释放:

在元素复制完成后,vector会释放原来的内存块,以避免内存泄漏。

5.更新指针和容量:

最后,vector会更新其内部指针,使其指向新的内存块,并更新其容量值以反映新的内存块大小。

6.需要注意的是,虽然增长因子通常是2,但这不是一个固定的规则。不同的编译器和标准库实现可能会有不同的增长策略。此外,由于内存分配和释放的开销,频繁地扩容可能会对性能产生负面影响。因此,在可能的情况下,建议使用reserve()成员函数来预先分配足够的内存空间,以减少扩容的次数并提高程序的性能。总的来说,vector扩容时内存分配的策略是灵活的,旨在平衡内存使用效率和程序性能之间的关系。


capacity在vector中的表现如何

这里我们依然借用一下上期内容的代码来说明:C++的动态数组vector

#include<iostream>
#include<vector>
using namespace std;
int main()
{
//创建动态数组
vector<int>v={1,2,3,4};
cout<<"size is"<<v.size()<<endl;
cout<<"capacity is"<<v.capacity()<<endl;
//遍历所有元素
for(int i=0;i<v.size();++i)
{
  cout<<v[i]<<endl;
}
 
//在尾部插入一个元素
v.push_back(5);
cout<<"size is"<<v.size()<<endl;
cout<<"capacity is"<<v.capacity()<<endl;
//遍历所有元素
for(int i=0;i<v.size();++i)
{
  cout<<v[i]<<endl;
}
 
//在尾部任意位置插入一个元素
v.insert(--v.end(),6);
cout<<"size is"<<v.size()<<endl;
cout<<"capacity is"<<v.capacity()<<endl;
//遍历所有元素
for(int i=0;i<v.size();++i)
{
  cout<<v[i]<<endl;
}
 
//在尾部移除一个元素
v.pop_back();
cout<<"size is"<<v.size()<<endl;
cout<<"capacity is"<<v.capacity()<<endl;
//遍历所有元素
for(int i=0;i<v.size();++i)
{
  cout<<v[i]<<endl;
}
 
//在尾部移除一个元素
v.erase(v.end()-1);
cout<<"size is"<<v.size()<<endl;
cout<<"capacity is"<<v.capacity()<<endl;
//遍历所有元素
for(int i=0;i<v.size();++i)
{
  cout<<v[i]<<endl;
}
 
return 0;
} 

 

 大家看上面的两张黑框框,这个就是cout的窗口,我们现在对照着代码和图片的结果观察。

解析:

一开始我们定义的vector数组的内容大小是4,预存储的大小也是4,这是因为我们的初始化的影响。然后我们在尾部添加一个元素,这是再看内容大小是5,预存储大小是6。这是因为我们添加了一个元素,导致vector数组自动的扩容,从而预存储大小变大。我们上面说到vector的扩容是按倍数来扩容的,这里的6就是4的1.5倍大小。然后我们在数组任意位置再插入一个数组,这时我们的内容大小变大到6,预存储大小不变(因为·够用,所以不会再变化)。之后的连着两次的删除元素都只会导致内容的大小变化(变小),预存储的大小不变,这是因为编译器以防万一,害怕内存不够用的机制。

这就是vector中的capacity的各种方面的体现。我们只有理解了这些基本的原理才会让我们在以后的C++道路上越来越通畅。


🆗到这里,这篇关于C++的动态数组vector番外之capacity就说完了,求一个免费的赞,感谢阅读,我们下期见。

下期预告:C++容器之字符串的详解

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

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

相关文章

基于无人机边沿相关 ------- IBUS、SBUS协议和PPM信号

文章目录 一、IBUS协议二、SBUS协议三、PPM信号 一、IBUS协议 IBUS&#xff08;Intelligent Bus&#xff09;是一种用于电子设备之间通信的协议&#xff0c;采用串行通信方式&#xff0c;允许多设备通过单一数据线通信&#xff0c;较低延迟&#xff0c;支持多主机和从机结构&a…

redis | Django小项目之Mysql数据库和Redis缓存的应用

Django小项目 需求整体架构图技术细节环境配置各文件配置settings.pyurls.pyviews.pyuser_update.html 结果相关代码补充r.hgetall(cacahe_key)new_data {k.decode():v.decode() for k,v in data.items()} 需求 整体架构图 技术细节 环境配置 django-admin startprojrct rmysi…

WIFI 应用层代码

1.0 定义枚举类型 typedef enum {WIFI_COMM_WAIT, // AT 等待命令WIFI_COMM_OK, // AT 命令完成WIFI_COMM_FALL, // AT 命令失败 }WifiCommState_t; 注&#xff1a;该枚举类型的作用是&#xff0c;定义三个成员变量&#xff0c;分别表示AT指令等待发送&#xff0c;AT指令…

unity游戏开发——(细)深入解析 Unity 地形系统:从基础到高级应用

Unity游戏开发 “好读书&#xff0c;不求甚解&#xff1b;每有会意&#xff0c;便欣然忘食。” 本文目录&#xff1a; Unity游戏开发 Unity游戏开发前言深入解析 Unity 地形系统&#xff1a;从基础到高级应用一、初识 Unity 地形系统1. 地形尺寸与分辨率 二、地形编辑工具详解1…

下拉菜单 匹配搜索

操作版本&#xff1a;Excel 2010 下拉菜单 涉及到的函数&#xff1a; INDIRECT函数&#xff1a;返回由文本字符串指定的引用 原文链接 一级下拉菜单 方法一&#xff1a;手动输入 选中要制作下拉菜单的单元格区域&#xff0c;单击【数据】-【数据有效性】-【序列】&#…

15.CentOS7升级内核

升级内核 1.配置镜像源 vim /etc/yum.repos.d/elrepo.repo[elrepo] nameelrepo baseurlhttps://mirrors.aliyun.com/elrepo/archive/kernel/el7/x86_64 gpgcheck0 enabled12.备份 cd /etc/yum.repos.d/ mv local.repo repo.bak/ 3.清缓存 yum clean all 4.升级内核 yum ins…

背部筋膜炎最好的恢复办法

背部筋膜炎是由于寒冷、精神紧张、潮湿或慢性劳损等因素造成的背部肌筋膜和肌组织发生水肿、纤维变性和渗出&#xff0c;其主要症状包括&#xff1a; 1、疼痛&#xff1a;患者通常会出现背部疼痛&#xff0c;这种疼痛在着凉或劳累时可能会加重。晨起时疼痛可能尤为明显&#x…

将两对象(重复属性不替换)合并成一个对象

将这两个对象合并成一个对象 const obj1 {"configType": "all","config": {"a":1} };const obj2 {"target_cluster": "dev-0821","type": "import","config": {"connector…

攻防世界-web题型-4星难度汇总-个人wp

Confusion1 进入页面查看源代码&#xff0c;发现有两个提示 访问第一个源码里面有个 /opt/flag_1de36dff62a3a54ecfbc6e1fd2ef0ad1.txt /opt/salt_b420e8cfb8862548e68459ae1d37a1d5.txt 不过我发现好像是只要访问404页面都有这两个。。。 另外这两个admin和login页面都没用…

如何把照片转换成PDF格式?分享3种好用的PDF转换方法

在数字化的时代中&#xff0c;各种格式的文件已经是我们平时办公中不可或缺的一部分&#xff0c;其中尤其是以图片、PDF这两种文件使用的最多&#xff0c;图片能够更加直观的表现内容&#xff0c;而PDF文档因其稳定性、兼容性等特性&#xff0c;也在办公中有独特的优势&#xf…

Pandas DataFrame的创建方法(Create DataFrame)

pandas是一个第三方数据分析库&#xff0c;其集成了大量的数据模型和分析工具&#xff0c;可以方便的处理和分析各类数据。其中主要对象类型有Series&#xff0c;DataFrame和Index。本文介绍DataFrame对象的基本创建方法。 关于DataFrame的基础用法&#xff0c;可以查看下面的…

随机生成n个字节os.urandom(n)

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 随机生成n个字节 os.urandom(n) [太阳]选择题 下列输出结果中正确的是? import os print("【执行】a os.urandom(2)") a os.urandom(2) print("【显示】a ", a) pri…

【Qt】输入类控件QDail

目录 输入类控件QDail 例子&#xff1a;调整窗口不透明度 输入类控件QDail 使用QDail表示一个旋钮&#xff0c;通过鼠标拖动旋钮可以完成一些相关的属性。 核心属性 属性说明 value 持有的数值. minimum 最⼩值 maximum 最⼤值 singleStep 按下⽅向键的时候改变的步⻓…

【Java数据结构】---二叉树OJ

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 文章目录 相同的树另一颗树的子树翻…

与copilot 结对编程系列 - log日志重复性检测 - 第4篇 - 网页UI界面

背景 细节可以参考这篇文章: 与copilot 结对编程系列 - log日志重复性检测 - 第1篇 - 总体介绍及效果展示 本文主要将数据库中存储的数据通过网页调用并展示出来, 以下是对详细解释。 web框架选择 当前场景使用 Flask 来展示网页信息. 主要原因如下&#xff1a; 轻量级和易…

如何使用JavaScript获取HTML表单中的值?

在开发中&#xff0c;我们经常需要获取用户在表单中输入的数据&#xff0c;然后进行处理或提交到服务器。今天我们就来聊一聊&#xff0c;如何用JavaScript获取HTML表单中的值。 使用 FormData 构造函数 FormData 是一个非常方便的工具&#xff0c;它可以把表单中的所有数据打包…

C++,std::chrono 详解

文章目录 1. 概述2. 时间点&#xff08;Time Points&#xff09;3. 时间间隔&#xff08;Durations&#xff09;4. 时钟&#xff08;Clocks&#xff09;5. 时间算术6. 时间转换7. 延时参考 1. 概述 std::chrono 是 C11 引入的一个库&#xff0c;用于处理日期和时间。它提供了一…

Unsloth 教程 - 如何微调 Llama-3并导出到 Ollama

本文翻译整理自&#xff1a;&#x1f999; How to Finetune Llama-3 and Export to Ollama https://docs.unsloth.ai/tutorials/how-to-finetune-llama-3-and-export-to-ollama 文章目录 1、什么是Unsloth&#xff1f;2、什么是Ollama&#xff1f;3、安装Unsloth4、选择要微调的…

博弈论总结

公平组合游戏&#xff08;Impartial Game&#xff09;的定义如下&#xff1a; 游戏有两个人参与&#xff0c;二者轮流做出决策&#xff0c;双方均知道游戏的完整信息&#xff1b; 任意一个游戏者在某一确定状态可以作出的决策集合只与当前的状态有关&#xff0c;而与游戏者无关…

pytorch深度学习基础 6(简单的参数估计学习3)

上一篇博客说了如何拟合一条直线ywxb&#xff0c;今天我们现在使用PyTorch进行相同的曲线拟合 拟合y x*x -2x 3 0.1(-1到1的随机值) 曲线 给定x范围&#xff08;0&#xff0c;3&#xff09; 生成数据 import numpy as np import matplotlib.pyplot as plt import torch as t…