[C++深入] --- vector容器浅析
vector是一个封装了动态大小数组的顺序容器,它能够存放各种类型的对象。 可以删除元素、可以插入元素、可以查找元素,做这些工作我们无需管理容器内存。容器内存管理,这种脏活累活全部交由vector管理。了解一下vector的内存管理策略,能够更加充分的利用内存。
1 vector内存分配策略
1.1 vector扩大容量的本质
vector 的大小和容量相等(size==capacity)也就是满载时,如果再向其添加元素,那么 vector 就需要扩容。vector 容器扩容的过程需要经历以下 3 步:
- 完全弃用现有的内存空间,重新申请更大的内存空间;
- 将旧内存空间中的数据,按原有顺序移动到新的内存空间中;
- 最后将旧的内存空间释放。
这也就解释了,为什么 vector 容器在进行扩容后,与其相关的指针、引用以及迭代器可能会失效的原因。
1.2 vector使用示例
通过一个vector简单示例,看看vector是如何管理内存的。
程序1
#include <iostream>
#include <vector>class MyClass {
public:MyClass() {++contruct_cnt;std::cout << this << ": MyClass constructor called " << contruct_cnt << " times" << std::endl;}~MyClass() {++deconstrcut_cnt;std::cout << this << ": MyClass deconstrcut called " << deconstrcut_cnt << " times" << std::endl;}MyClass(const MyClass &tmp) {++copy_construct_cnt;std::cout << this << ": MyClass copy_constructor called " << copy_construct_cnt << " times" << "copy from " << &tmp << std::endl;}
private: static int contruct_cnt;static int deconstrcut_cnt;static int copy_construct_cnt;
};int MyClass::contruct_cnt = 0;
int MyClass::deconstrcut_cnt = 0;
int MyClass::copy_construct_cnt = 0; void VectorTest1()
{MyClass a, b, c, d, e;std::vector<MyClass> myVector;std::cout << std::endl << "======a======" << std::endl;myVector.push_back(a);std::cout << "vector capacity is " << myVector.capacity() << std::endl;std::cout << "vector size is "<< myVector.size() << std::endl;std::cout << std::endl <<"======b======" << std::endl;myVector.push_back(b);std::cout << "vector capacity is " << myVector.capacity() << std::endl;std::cout << "vector size is "<< myVector.size() << std::endl;std::cout << std::endl << "=======c=====" << std::endl;myVector.push_back(c);std::cout << "vector capacity is " << myVector.capacity() << std::endl;std::cout << "vector size is "<< myVector.size() << std::endl;std::cout << std::endl << "=======d=====" << std::endl;myVector.push_back(d);std::cout << "vector capacity is " << myVector.capacity() << std::endl;std::cout << "vector size is "<< myVector.size() << std::endl;std::cout << std::endl << "========e====" << std::endl;myVector.push_back(e); std::cout << "vector capacity is " << myVector.capacity() << std::endl;std::cout << "vector size is "<< myVector.size() << std::endl;// 当myVector离开作用域时,它的析构函数会被调用,从而调用每个元素的析构函数
}int main() {VectorTest1();return 0;
}
执行输出结果如下:
ThinkPad-P15v-Gen-2i:~/work/ybb$ ./a.out
0x7ffd8b07403b: MyClass constructor called 1 times
0x7ffd8b07403c: MyClass constructor called 2 times
0x7ffd8b07403d: MyClass constructor called 3 times
0x7ffd8b07403e: MyClass constructor called 4 times
0x7ffd8b07403f: MyClass constructor called 5 times======a======
0x55c2cb9282c0: MyClass copy_constructor called 1 timescopy from 0x7ffd8b07403b
vector capacity is 1
vector size is 1======b======
0x55c2cb9282e1: MyClass copy_constructor called 2 timescopy from 0x7ffd8b07403c
0x55c2cb9282e0: MyClass copy_constructor called 3 timescopy from 0x55c2cb9282c0
0x55c2cb9282c0: MyClass deconstrcut called 1 times
vector capacity is 2
vector size is 2=======c=====
0x55c2cb9282c2: MyClass copy_constructor called 4 timescopy from 0x7ffd8b07403d
0x55c2cb9282c0: MyClass copy_constructor called 5 timescopy from 0x55c2cb9282e0
0x55c2cb9282c1: MyClass copy_constructor called 6 timescopy from 0x55c2cb9282e1
0x55c2cb9282e0: MyClass deconstrcut called 2 times
0x55c2cb9282e1: MyClass deconstrcut called 3 times
vector capacity is 4
vector size is 3=======d=====
0x55c2cb9282c3: MyClass copy_constructor called 7 timescopy from 0x7ffd8b07403e
vector capacity is 4
vector size is 4========e====
0x55c2cb9282e4: MyClass copy_constructor called 8 timescopy from 0x7ffd8b07403f
0x55c2cb9282e0: MyClass copy_constructor called 9 timescopy from 0x55c2cb9282c0
0x55c2cb9282e1: MyClass copy_constructor called 10 timescopy from 0x55c2cb9282c1
0x55c2cb9282e2: MyClass copy_constructor called 11 timescopy from 0x55c2cb9282c2
0x55c2cb9282e3: MyClass copy_constructor called 12 timescopy from 0x55c2cb9282c3
0x55c2cb9282c0: MyClass deconstrcut called 4 times
0x55c2cb9282c1: MyClass deconstrcut called 5 times
0x55c2cb9282c2: MyClass deconstrcut called 6 times
0x55c2cb9282c3: MyClass deconstrcut called 7 times
vector capacity is 8
vector size is 5
0x55c2cb9282e0: MyClass deconstrcut called 8 times
0x55c2cb9282e1: MyClass deconstrcut called 9 times
0x55c2cb9282e2: MyClass deconstrcut called 10 times
0x55c2cb9282e3: MyClass deconstrcut called 11 times
0x55c2cb9282e4: MyClass deconstrcut called 12 times
0x7ffd8b07403f: MyClass deconstrcut called 13 times
0x7ffd8b07403e: MyClass deconstrcut called 14 times
0x7ffd8b07403d: MyClass deconstrcut called 15 times
0x7ffd8b07403c: MyClass deconstrcut called 16 times
0x7ffd8b07403b: MyClass deconstrcut called 17 times
上面的代码,加了很多打印,可以很好的分析程序执行的情况,这里主要说一下myVector在析构的时候,要调用存放在vector中元素的析构,再释放myVector占用的空间。
同时可以看到在填充vector的时候,会发生大量的拷贝构造,造成资源浪费,下面给出一个极端示例展示Vector在push_back时调用的拷贝构造函数次数。
程序2
#include <iostream>
#include <vector>class MyClass {
public:MyClass() {++contru
相关文章:
[C++深入] --- vector容器浅析
vector是一个封装了动态大小数组的顺序容器,它能够存放各种类型的对象。 可以删除元素、可以插入元素、可以查找元素,做这些工作我们无需管理容器内存。容器内存管理,这种脏活累活全部交由vector管理。了解一下vector的内存管理策略,能够更加充分的利用内存。 1 vector内存…...

用MySQL和navicatpremium做一个项目—(财务管理系统)。
1 ER图缩小的话怕你们看不清,所以截了两张图 2 vsdx绘图结果 3DDL和DML,都有点长分了好多次上传,慢慢看 DDL -- 用户表 CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,username VARCHAR(50) NOT NULL UNIQUE COMMENT 用…...

Jenkins教程-5-gitee自动化测试任务构建
上一小节我们学习了Jenkins构建gitlab自动化测试任务的方法,本小节我们讲解一下gitee自动化测试任务的构建方法。 接下来我们以windows系统为例,讲解一下构建实际自动化测试任务的具体步骤。 安装git和gitee插件 点击进入Jenkins插件管理页面 安装完插…...

CAN-bus总线在冷链运输中的应用
CAN-bus总线在冷链运输中的应用 如图1所示,疫苗冷链是指为保证疫苗从疫苗生产企业到接种单位运转过程中的质量而装备的存储、运输冷藏设施、设备。由于疫苗对温度敏感,从疫苗制造的部门到疫苗使用的现场之间的每一个环节,都可能因温度过高而失效。在储运过程中,一旦温度超…...
Vue 与 React 区别
Vue.js和React是现代Web开发中两种非常流行的前端框架,两者在**核心概念、组件以及生态系统扩展性**等方面存在区别。具体分析如下: 1. **核心概念** - **Vue**:Vue是一个渐进式JavaScript框架,它致力于视图层,易于上手…...
docker+[nginx] 部署nacos2.x 集群
docker+[nginx] 部署nacos2.x 集群 由于机器有限,本文搭建伪集群 准备: nacos1 :192.168.50.9:8848 nacos2:192.168.50.9:8858 nacos3:192.168.50.9:8868 mysql nginx 【可选,见文末】 创建容器共享网络 便于直接使用容器名连接mysql,如果不创建,连接mysql直接使用i…...

Linux学习第54天:Linux WIFI 驱动:蓝星互联
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 数字化、现代化的今天,随处的WIFI给与了大众极大的方便,也感受到了科技的力量。万物互联、无线互联越来越成为一个不可逆转的趋势。现在比较火…...

芯片后端之 PT 使用 report_timing 产生报告如何阅读
今天,就PT常用的命令,做一个介绍,希望对大家以后的工作,起到帮助作用。 在PrimeTime中,使用report_timing -delay max命令生成此报告。switch -delay max表示定时报告用于设置(这是默认值)。 首先,我们整…...
基于elastic stack搭建的ELK系统资源占用预估
1、ES 1.1 内存:ES非常消耗内存,不是JVM用到的内存,而是机器的物理内存,ES在运行期间对JVM Heap(堆内存)的需求较小 实践建议: 数据量过百万,建议单台服务器的内存至少要有16GB;数据量过亿,建议单台服务器的内存至少要有64GB 1.2 CPU:ES集…...
LiteDB - 一个单数据文件 .NET NoSQL 文档存储
LiteDB 一个小巧、快速、轻量级的 NoSQL 嵌入式数据库。 Serverless NoSQL 文档存储类似于 MongoDB 的简单 API100% C# 代码,支持 .NET 3.5 / .NET 4.0 / NETStandard 1.3 / NETStandard 2.0,单 DLL (小于 300 kb)支持线程和进程安全支持文档/操作级别的 ACID支持写失败后的数…...

视觉理解与图片问答,学习如何使用 GPT-4o (GPT-4 Omni) 来理解图像
🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、引言 OpenAI 最新发布的 GPT-4 Omni 模型,也被称为 GPT-4o,是一个多模态 AI 模型,旨在提供更加自然和全面的人机交互体验。 GPT-4o 与 GPT-4 Turbo 都具备视觉功…...

【LocalAI】(13):LocalAI最新版本支持Stable diffusion 3,20亿参数图像更加细腻了,可以继续研究下
最新版本v2.17.1 https://github.com/mudler/LocalAI/releases Stable diffusion 3 You can use Stable diffusion 3 by installing the model in the gallery (stable-diffusion-3-medium) or by placing this YAML file in the model folder: Stable Diffusion 3 Medium 正…...

云计算【第一阶段(19)】磁盘管理与文件系统 LVM与磁盘配额(二)
目录 一、LVM概述 1.1、LVM机制的基本概念 编辑 1.2、LVM的管理命令 1.3、lvm存储 两种机制 1.4、lvm应用实例 二、磁盘配额概述 2.1、设置磁盘配额 2.2.1、实现磁盘限额的条件 2.2.2、linux磁盘限额的特点 2.2.3、磁盘配额管理 一、LVM概述 1.1、LVM机制的基本概…...

基于C++实现的EventLoop与事件驱动编程
一,概念介绍 事件驱动编程(Event-Driven)是一种编码范式,常被应用在图形用户界面,应用程序,服务器开发等场景。 采用事件驱动编程的代码中,通常要有事件循环,侦听事件,…...

Android高级面试_8_热修补插件化等
Android 高级面试:插件化和热修复相关 1、dex 和 class 文件结构 class 是 JVM 可以执行的文件类型,由 javac 编译生成;dex 是 DVM 执行的文件类型,由 dx 编译生成。 class 文件结构的特点: 是一种 8 位二进制字节…...

显卡GTX与RTX有什么区别?哪一个更适合玩游戏?
游戏发烧友们可能对游戏显卡并不陌生,它直接关系到游戏画面的流畅度、细腻程度和真实感。在众多显卡品牌中,英伟达的GTX和RTX系列显卡因其出色的性能而备受关注。 一、GTX与RTX的区别 架构差异 GTX系列显卡采用的是Pascal架构,这是英伟达在…...

QT自定义信号和槽函数
在QT中最重要也是必须要掌握的机制,就是信号与槽机制,在MFC上也就是类型的机制就是消息与响应函数机制 在QT中我们不仅要学会如何使用信号与槽机制,还要会自定义信号与槽函数,要自定义的原因是系统提供的信号,在一些情…...
Atcoder Beginner Contest 359
传送门 A - Count Takahashi 时间限制:2秒 内存限制:1024MB 分数:100分 问题描述 给定 N 个字符串。 第 i 个字符串 () 要么是 Takahashi 要么是 Aoki。 有多少个 i 使得 等于 Takahashi ? 限制 N 是整数。每个…...

无线通讯几种常规天线类别简介
天线对于无线模块来说至关重要,合适的天线可以优化通信网络,增加其通信的范围和可靠性。天线的选型对最后的模块通信影响很大,不合适的天线会导致通信质量下降。针对不同的市场应用,天线的材质、安置方式、性能也大不一样。下面简…...

最大团问题--回溯法
一、相关定义 给定一个无向图 ,其中 V 是图的顶点集,E图的边集 完全图:如果无向图中的任何一对顶点之间都有边,这种无向图称为完全图 完全子图:给定无向图 ,如果 ,且对应任意 且 ,则…...

UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...