C++之STL(二三)

1、vector源码刨析

1.1、数据结构以及动态扩充算法

其实vector内部有三个指针,分别是数据的第一个元素Myfirst、数据的最后一个元素的下一个位置Mylast,最后一个空间的下一个位置Myend;当你插入数据的时候,先判断当前容量够不够,不够的话通过内存分配子扩充容量,至于扩充的算法,可能有些编译器不大相同,像vc6.0的话,就是成倍扩充,比如当前是2,扩充到4,4不够用了之后,又扩充到8,以此类推。但是像visual studio,就是按照容量的一半进行扩充。

#include <vector>
#include <iostream>
using namespace std;int main() {vector<int> v;v.push_back(1);cout << v.capacity() << endl;v.push_back(1);cout << v.capacity() << endl;v.push_back(1);cout << v.capacity() << endl;v.push_back(1);cout << v.capacity() << endl;v.push_back(1);cout << v.capacity() << endl;v.push_back(1);cout << v.capacity() << endl;v.push_back(1);cout << v.capacity() << endl;v.push_back(1);cout << v.capacity() << endl;return 0;
}//输出
1
2
4
4
8
8
8
8

1.2、如何实现连续空间

如果是从尾部插入,分配内存结束后,先在尾部的位置插入数据,然后再将之前的数据一个个复制过去。

如果是从中间插入,分配内存后,先在该位置插入数据,然后再将该位置的前面数据搬下来,然后将该位置的后面数据依次搬到该位置的后面。

1.3、内存分配子

先上代码

#include <vector>
#include <iostream>
using namespace std;class Test
{
public:Test(){cout << "Test() ..." << endl;}Test(const Test& other){cout << "copy Test ..." << endl;}~Test(){cout << "~Test() ..." << endl;}
};int main() {vector<Test> v;Test t1;Test t2;Test t3;v.push_back(t1);v.push_back(t2);v.push_back(t3);return 0;
}// 输出
Test() ...
Test() ...
Test() ...
copy Test ...
copy Test ...
copy Test ...
~Test() ...
copy Test ...
copy Test ...
copy Test ...
~Test() ...
~Test() ...
~Test() ...
~Test() ...
~Test() ...
~Test() ...
~Test() ...
~Test() ...

根据例子来分析分配内存的过程

前三行的构造:是定义了三个变量打印出来的;

v.push_back(t1)具体过程:

1、先是调用_Allocate函数。_Allocate里面会调用operator new分配新内存,然后算出偏移量,也就是要在哪插入数据

2、然后调用_Ufill函数将数据插入进去。_Ufill里面最终会调用placement new去调用拷贝构造函数将复制的数据插入新内存。(在这边就会打印出第四行的拷贝构造)

这边为什么不直接调用new operator直接开辟空间和调用拷贝构造?因为要算出偏移量,每一个类型的偏移量都不一样,所以必须先分配内存,然后再根据偏移量插入到新内存。

3、然后再调用_Move将该位置的前面数据搬到新空间当中去(因为这是第一个元素,所以没有前面数据)

4、然后再调用_Move将该位置的后面数据搬到新空间当中去(因为这是第一个元素,所以没有后面数据)

5、代码中这边还有需要显示调用析构函数和释放旧内存,因为这是第一块内存,而且构造出来的数据是要放在第一块内存中,所以这边没有调用析构和释放内存。

6、然后将三个指针改成相对应的位置。

v.push_back(t2)具体过程:

第五行的拷贝原理同第四行。

前两步跟上面一样;

3、调用_Move将该位置之前的数据遍历,遍历里面调用placement new,调用拷贝构造将数据拷贝到新内存中,因为这个t2前面只有一个t1,所以就只拷贝t1,所以打印出了第六行的拷贝构造函数。

4、同上

5、这边已经将数据都拷贝到新的内存当中了,所以需要释放旧的内存。最后面会显示的调用析构函数,打印出了第七行的析构函数。然后再调用operator delete释放上面operator new的内存。这边析构的是:旧内存中的数据,因为已经将旧内存中的数据拷贝到新内存中了,旧内存就没用了,此时旧内存有t1和t2,所以就只打印出两行析构。跟第一个push_back不同的是,第一个的时候没有旧数据,所以不需要删除和析构。

6、然后将三个指针改成相对应的位置。

v.push_back(t3)具体过程:

第八行的拷贝原理同第四行。

前两步跟上面一样;

3、调用_Move将该位置之前的数据遍历,遍历里面调用placement new,调用拷贝构造将数据拷贝到新内存中,因为这个t3前面有t1和t2,拷贝了两个,所以打印出了第九、十行的拷贝构造函数。

4、同上(注意,如果是在中间插入,那这边第四步调用的函数和第三步一样,只是参数不一样,里面都是遍历,然后拷贝)

5、这边已经将数据都拷贝到新的内存当中了,所以需要释放旧的内存。最后面会显示的调用析构函数,打印出了第十一、十二行的析构函数。然后再调用operator delete释放上面operator new的内存。这边析构的是:旧内存中的数据,因为已经将旧内存中的数据拷贝到新内存中了,旧内存就没用了,此时旧内存就只有一个t1,所以就只打印出一行析构。跟第一个push_back不同的是,第一个的时候没有旧数据,所以不需要删除和析构。

6、然后将三个指针改成相对应的位置。

剩下的6个析构函数,分别是t1t2t3生命周期结束的时候调用,还有v生命周期结束的时候也会去销毁里面的元素,所以v里面也有三个析构,这样加起来,就是上面代码输出的样子。

这边再复习一下new的三种用法:

new operator:分配空间+构造函数

opearator new:只分配空间,不调用构造函数

placement new:不分配空间,调用构造函数

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

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

相关文章

尚品汇项目2

p68 加入产品个数操作 p69 加入购物车

立讯精密:“果链一哥”怎么摆脱依赖症

AI手机创新赋能&#xff0c;隔岸苹果股价走出历史新高&#xff0c;消费电子有望迎来复苏&#xff1f; 这里我们聊聊苹果产业链代工龙头——立讯精密 作为早早入场的代工企业&#xff0c;立讯精密曾经吃足“果链”红利&#xff0c;如今摆在它面前的是增长、毛利、安全等难题。 …

人工智能—美国加利福尼亚州房价预测实战

引言 在当今快速发展的房地产市场中&#xff0c;房价预测已成为一个至关重要的领域。它不仅关系到投资者的决策&#xff0c;也直接影响到普通购房者的生活质量。特别是在美国加利福尼亚州&#xff0c;这个以其高房价和房地产市场的波动性而闻名的地方&#xff0c;准确的房价预…

TF-IDF、BM25传统算法总结

1. TF-IDF算法 F-IDF&#xff08;词频-逆文档频率&#xff09;是一种用于衡量文本中词语重要性的方法&#xff0c;特别适用于信息检索和文本挖掘任务。下面会拆分为两部分深入讲解TF-IDF的计算过程&#xff0c;以便更好地理解。 TF-IDF的计算过程可以分为两个主要部分&#xf…

【漏洞复现】契约锁电子签章平台 add 远程命令执行漏洞(XVE-2023-23720)

0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系(m_coord)

03 - matlab m_map地学绘图工具基础函数 - 设置坐标系&#xff08;m_coord&#xff09; 0. 引言1. m_proj使用方法2. 结语 0. 引言 上一篇介绍了m_proj函数用于初始化投影&#xff0c;本篇介绍的函数m_coord用于初始化地理坐标系或地磁坐标系&#xff0c;地理/地磁坐标系和投影…

xss一些笔记

&#xff08;乱写的一些笔记&#xff09; innerHTML只防script像是img就不会防 innerText都防 上面代码执行避免用户交互 js也可以用’‘执行 例子 alert’1‘ document.location.hash // #号后的部分&#xff0c;包括#号 document.location.host // 域名…

黑马苍穹外卖4 店铺营业状态设置+Redis基础

店铺营业状态设置 Redis MySQL Java并发 JavaMVC 计算机网络 操作系统 算法&#xff0c;后端面试主要是这些&#xff0c;外加项目 Redis 数据库&#xff0c;基于内存存储的key-value结构。 mysql是磁盘存储&#xff0c;通过二维表存储。 在文件夹目录打开cmd 服务端&#xf…

YOLOv10(6):YOLOv10基于TensorRT的部署(基于INetworkDefinition)

1. 写在前面 我们在前面已经讲过很多关于YOLOv10的一些知识点&#xff0c;也简单理了一下如何训练自己的数据。 现在本篇文章主要是讲解一下如何在TensorRT中部署YOLOv10&#xff0c;相信经过这一步&#xff0c;各位小伙伴已经能够无限的接近于将YOLOv10产品化了。 另一个需要说…

LeetCode-day17-2713. 矩阵中严格递增的单元格数

LeetCode-day17-2713. 矩阵中严格递增的单元格数 题目描述示例示例1&#xff1a;示例2&#xff1a;示例3&#xff1a; 思路代码 题目描述 给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat&#xff0c;你可以选择任一单元格作为 起始单元格 。 从起始单元格出发&#xff…

Perplexity AI — 探索网络,发掘知识,沟通思想

体验地址&#xff1a;Perplexity AI &#xff08;国外网站访问需要梯子&#xff09; Perplexity AI是一款功能强大的人工智能搜索引擎&#xff0c;其特点和优势主要体现在以下几个方面&#xff1a; 功能&#xff1a; 自然语言搜索&#xff1a;Perplexity AI可以理解用户的自然…

Shopify 如何实现 Sticky 功能

Shopify 如何实现 Sticky 功能 介绍 在网页设计中&#xff0c;Sticky 功能是一种常见的技术&#xff0c;它使得网页上的元素在滚动时保持固定位置。这对于创建吸引人的用户体验和提高网站的可用性非常重要。Shopify 作为一个流行的电商平台&#xff0c;提供了丰富的功能和工具…

进化版ChatGPT的Siri今年无缘上线!苹果正打造史上最薄iPhone 17

目录 01 超强Siri助手预计2025年上线 02 集成ChatGPT但没有买单 03 iPhone 17更轻薄 最新报道称&#xff0c;苹果的AI功能将在未来几个月逐步推出&#xff0c;并持续到2025年。 据称&#xff0c;今年夏天结束前&#xff0c;开发者们仍无法试用和体验。 因此&#xff0c;在即…

MySQL系列-语法说明以及基本操作(一)

1、前言 主要讲解MySQL的基本语法 官网文档 https://docs.oracle.com/en-us/iaas/mysql-database/doc/getting-started.html 关于MySQL的基本语法&#xff0c;关于数据类型、表的操作、数据操作、事务、备份等&#xff0c;可参考 http://www.voidme.com/mysql 2、数据类型 数…

Oracle中递归查询(START WITH……CONNECT BY……)

一、基本语法 在Oracle中START WITH……CONNECT BY……一般用来查找存在父子关系的数据&#xff0c;也就是树形结构的数据。 SELECT * FROM TABLE WHERE 条件3 START WITH 条件1 CONNECT BY 条件2;start with [condition]&#xff1a;设置起点&#xff0c;用来限制第一层的数…

线程间通信

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 我们已经知道进程之间不能直接共享信息&#xff0c;那么线程之间可以共享信息吗&#xff1f;我们通过一个例子来验证一下。定义一个全局变量g_num&am…

【腾讯云智笔试题——分苹果两种解法】

文章目录 题目描述解题思路&#xff1a;疑惑解析代码中明明是两个嵌套的for循环时间复杂度为什么是O&#xff08;m&#xff09;&#xff1f; 题目描述 有m个苹果&#xff0c;n个小孩。每个小孩都有一个编号&#xff0c;小明的编号是。要尽量公平的分苹果&#xff0c;相邻编号的…

C++ 类与对象的使用要点(超详细解析,小白必看系列)

1.面向过程和面向对象初步认识 C语言是面向过程的语言&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题 例如&#xff1a;洗衣服 C是基于对象的&#xff0c;关注的是对象&#xff0c;将一件事拆分成不同的对象&#xff0c;靠对…

[NewStarCTF 2023 公开赛道]R!C!E!

好久没写了。今天儿弄一个rce 题很直接&#xff0c;好久没这么直白的题了&#xff0c;看源码 <?php highlight_file(__FILE__); if(isset($_POST[password])&&isset($_POST[e_v.a.l])){$passwordmd5($_POST[password]);$code$_POST[e_v.a.l];if(substr($password…