【C++ 面试 - STL】每日 3 题(九)

news2024/9/26 3:19:47

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

25. 说一下 STL 每种容器对应的迭代器

暂时无法在飞书文档外展示此内容

26. STL 的两级空间配置器

allocate 包装 malloc,deallocate 包装 free

allocator 就是用来分配内存的,最重要的两个函数是 allocate 和 deallocate,就是用来申请内存和回收内存的,外部(一般指容器)调用的时候只需要知道这些就够了。

1、首先明白为什么需要二级空间配置器?

我们知道动态开辟内存时,要在堆上申请,但若是我们需要频繁的在堆开辟释放内存,则就会在堆上造成很多外部碎片,浪费了内存空间;
每次都要进行调用 malloc、free 函数等操作,使空间就会增加一些附加信息,降低了空间利用率;
随着外部碎片增多,内存分配器在找不到合适内存情况下需要合并空闲块,浪费了时间,大大降低了效率。
于是就设置了二级空间配置器,当开辟内存 <= 128 bytes 时,即视为开辟小块内存,则调用二级空间配置器。
关于 STL 中一级空间配置器和二级空间配置器的选择上,一般默认选择的为二级空间配置器。 如果大于 128 字节再转去一级配置器器。

一级配置器

一级空间配置器中重要的函数就是 allocate、deallocate、reallocate。 一级空间配置器是以 malloc(),free(),realloc() 等 C 函数执行实际的内存配置。大致过程是:
1、直接 allocate 分配内存,其实就是 malloc 来分配内存,成功则直接返回,失败就调用处理函数。
2、如果用户自定义了内存分配失败的处理函数就调用,没有的话就返回异常。
3、如果自定义了处理函数就进行处理,完事再继续分配试试。

在这里插入图片描述
二级配置器

在这里插入图片描述
1、维护 16 条链表,分别是 0-15 号链表,最小 8 字节,以 8 字节逐渐递增,最大 128 字节,你传入一个字节参数,表示你需要多大的内存,会自动帮你校对到第几号链表(如需要 13 bytes 空间,我们会给它分配 16 bytes 大小),在找到第 n 个链表后查看链表是否为空,如果不为空直接从对应的 free_list 中拔出,将已经拨出的指针向后移动一位。

2、对应的 free_list 为空,先看其内存池是不是空时,如果内存池不为空:
(1)先检验它剩余空间是否够 20 个节点大小(即所需内存大小(提升后) * 20),若足够则直接从内存池中拿出 20 个节点大小空间,将其中一个分配给用户使用,另外 19 个当作自由链表中的区块挂在相应的 free_list 下,这样下次再有相同大小的内存需求时,可直接拨出。
(2)如果不够 20 个节点大小,则看它是否能满足 1 个节点大小,如果够的话则直接拿出一个分配给用户,然后从剩余的空间中分配尽可能多的节点挂在相应的 free_list 中。
(3)如果连一个节点内存都不能满足的话,则将内存池中剩余的空间挂在相应的 free_list 中(找到相应的 free_list),然后再给内存池申请内存,转到 3。

3、内存池为空,申请内存。此时二级空间配置器会使用 malloc() 从 heap 上申请内存,(一次所申请的内存大小为 2 * 所需节点内存大小(提升后)* 20 + 一段额外空间),申请 40 块,一半拿来用,一半放内存池中。

4、malloc 没有成功。在第三种情况下,如果 malloc() 失败了,说明 heap 上没有足够空间分配给我们了,这时,二级空间配置器会从比所需节点空间大的 free_list 中一一搜索,从比它所需节点空间大的 free_list 中拔除一个节点来使用。如果这也没找到,说明比其大的 free_list 中都没有自由区块了,那就要调用一级适配器了。而一级配置器其实也是使用 malloc(),但是它有 out-of-memeory 处理机制,或许有机会拿其它的内存拿来此处使用。如果还是申请不成功,就会发出 bad_alloc 异常。
释放时调用 deallocate() 函数,若释放的 n > 128,则调用一级空间配置器,否则就直接将内存块挂上自由链表的合适位置。

STL 二级空间配置器虽然解决了外部碎片与提高了效率,但它同时增加了一些缺点:

  1. 因为自由链表的管理问题,它会把我们需求的内存块自动提升为 8 的倍数,这时若你需要 1 个字节,它会给你 8 个字节,即浪费了 7 个字节,所以它又引入了内部碎片的问题,若相似情况出现很多次,就会造成很多内部碎片;
  2. 二级空间配置器是在堆上申请大块的狭义内存池,然后用自由链表管理,供现在使用,在程序执行过程中,它将申请的内存一块一块都挂在自由链表上,即不会还给操作系统,并且它的实现中所有成员全是静态的,所以它申请的所有内存只有在进程结束才会释放内存,还给操作系统,由此带来的问题有:
  3. 即我不断的开辟小块内存,最后整个堆上的空间都被挂在自由链表上,若我想开辟大块内存就会失败;
  4. 若自由链表上挂很多内存块没有被使用,当前进程又占着内存不释放,这时别的进程在堆上申请不到空间,也不可以使用当前进程的空闲内存,由此就会引发多种问题。

一级分配器

GC4.9 之后就没有第一级了,只有第二级

二级分配器

—— default_alloc_template 剖析
有个自动调整的函数:你传入一个字节参数,表示你需要多大的内存,会自动帮你校对到第几号链表(0-15 号链表,最小 8 字节,最大 128 字节)
allocate 函数:如果要分配的内存大于 128 字节,就转用第一级分配器,否则也就是小于 128 字节。那么首先判断落在第几号链表,定位到了,先判断链表是不是空,如果是空就需要充值,(调节到 8 的倍数,默认一次申请 20 个区块,当然了也要判断 20 个是不是能够申请到,如果只申请到一个那就直接返回好了,不止一个的话,把第 2 到第 n 个挨个挂到当前链表上,第一个返回回去给容器用,n 是不大于 20 的,当然了如果不在 1 - 20 之间,那就是内存碎片了,那就先把碎片挂到某一条链表上,然后再重新 malloc 了,malloc 2*20 个块)去内存池去拿或者重新分配。

27. sort 的底层实现

std::sort 主要是三种算法的结合体:插入排序,快速排序,堆排序。

在这里插入图片描述

std::sort 根据上文提到的几种算法的优缺点,对排序算法进行整合。

  1. 快速排序,递归排序到一定深度后,数据已经被分为多个子区域,子区域里面的数据可能是无序的,但是子区域之间已经是有序了。
  2. 在这多个子区域里,如果某个子区域数据个数大于阈值(16),采用堆排序,使得某个子区域内部有序。
  3. 剩下的没有被堆排序的小区域,数据量都是小于阈值的,最后整个数据区域采用插入排序。
    在这里插入图片描述
  4. std::sort 采用的是分治思维,先采用快速排序,将整个区域分成多个子区域,每个子区域内部根据数据量采用不同算法。
  5. 分治后,各个子区域局部有序后再通过整个区域进行排序。

哪些容器可以用 sort 进行排序?

STL 的所有关联型容器都有自动排序的功能(底层结构采取 RB-tree),所以不需要用到这个 sort 算法。
至于序列式容器中的 stack、queue 和 priority-queue 都有特定的出入口,不允许用户对元素进行排序。
剩下的 vector、deque 和 list,前两者的迭代器都属于 RandomAccessIterators,适合使用 sort 算法;list 的迭代器则属于 BidirectionalIterators;不在 STL 标准之列的 slist,其迭代器更属于 ForwardIterator,都不适合使用 sort 算法,如果是要对 list 或者 slist 中的元素进行排序,应该使用他们自己的 member function sort()。

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

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

相关文章

开学季有什么必备好物?这篇好物推荐不要错过!

随着开学季节的来临&#xff0c;众多商家纷纷推出一系列的优惠活动&#xff0c;这使得开学季成为了购物的理想时机。无论是电子产品还是日常用品&#xff0c;此时购买都非常合算。下面&#xff0c;我将为大家推荐几款开学季不可或缺的好物。开学季有什么必备好物&#xff1f;如…

AI艺术创作福利:免费领取红包封面,Meo喵、龙小金与你共庆佳节!

&#x1f389;&#x1f409;&#x1f431; 亲爱的朋友们&#xff0c;佳节将至&#xff0c;北京时间24年9月6日18:00&#xff0c;我们通过Midjourney的AI艺术创作和ComfyUI设计&#xff0c;特别为大家准备了一份特别的礼物——1588个独家设计的微信红包封面&#xff01;欢迎关注…

2024年全国大学生数学建模比赛思路、题目、代码

竞赛时间及参赛建议 竞赛开始时间&#xff1a;北京时间2024年9月5日18:00 竞赛结束时间&#xff1a;北京时间2024年9月8日20:00 关于今年每道题的思路&#xff0c;可以关注我gzh回复”国赛A/B/C/D/E题“获取 需要帮助的可以关注公众号&#xff0c;在功能栏点击联系我们&…

利用大模型实时提取和检索多模态数据探索-利用 Indexify 进行文档分析

概览 传统的文本提取方法常常无法理解非结构化内容&#xff0c;因此提取数据的数据往往是错误的。本文将探讨使用 Indexify&#xff0c;一个用于实时多模态数据提取的开源框架&#xff0c;来更好地分析pdf等非结构化文件。我将介绍如何设置 Indexify&#xff0c;包括服务器设置…

智能设计#生成式海报

终于有机会把智能海报&#xff0c;做个升级了。比几年前的做法优雅了很多&#xff0c;也没有了素材有限的困扰。1 点一次&#xff0c;生成4张图2 选1张图&#xff0c;点海报生成3 得到封面海报

vue----一维数组根据同一id改成二维数组

vue----一维数组根据同一id改成二维数组 初始数据&#xff08;多个dimension_id值一样&#xff09;&#xff1a; 转换后的数据&#xff08;类似于&#xff09;&#xff1a; [{dimension_id: xxxxxxxxx,desc: 111,res: [{ id: 4444444, self_score: 90 },{ id: 5555555, sel…

PulseSensor心率传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.接线图 2.引脚描述 3.工作原理&#xff1a;光电容积法原理 4.工作原理&#xff1a;心率采样数据处理算法 三、程序设计 main.c文件 adcx.h文件 adc.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 PulseSensor传感器是一种基…

4.1 溪降技术:峡谷等级规划

Content 4.1 溪降技术&#xff1a;峡谷等级规划概述观看视频课程电子书&#xff1a;峡谷等级评定FFME&#xff08;法国&#xff09;系统FFME等级评定系统 - 工作原理垂直特征或“V”等级水特征或“A”等级难度/持续时间 ACA&#xff08;美国&#xff09;等级评定系统ACA等级评定…

啊!FLUX 模型爆火,电商人爱死!好用快冲!

今天&#xff0c;我来分享一批FLUX模型搭配使用的LORA&#xff0c;可能有些朋友不太了解FLUX模型&#xff0c;这里也做快速做个简要介绍&#xff1a;FLUX模型是在2024年8月1日发布的。这款模型出自Black Forest Labs之手&#xff0c;其团队正是Stable Diffusion的原班人马&…

PCI Express 体系结构导读摘录(三)

系列文章目录 PCI Express 体系结构导读摘录&#xff08;一&#xff09; PCI Express 体系结构导读摘录&#xff08;二&#xff09; PCI Express 体系结构导读摘录&#xff08;三&#xff09; 文章目录 系列文章目录第 6 章  PCIe 总线的事务层6. 1  TLP 的格式6. 1. 1 通用 …

【运维自动化-作业平台】如何快速执行脚本和分发文件

脚本执行和文件分发是作业平台最基本、最核心的两个原子功能&#xff0c;主要分页面快速执行和作业里步骤引用&#xff0c;使用逻辑一样&#xff0c;一起来看看具体如何使用快速执行脚本 核心实现原理就是基于gse的命令管道&#xff0c;把脚本内容以WebPortal的方式透传到目标…

基于yolov8的口罩佩戴检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的口罩佩戴检测系统是一款利用深度学习技术&#xff0c;特别是YOLOv8算法&#xff0c;实现高效、准确检测人脸是否佩戴口罩的系统。YOLOv8作为YOLO系列算法的最新版本&#xff0c;在检测速度和准确性上进行了显著优化&#xff0c;能够实时处理图像和视…

UDP协议程序设计

文章目录 前言一、UDP程序设计是什么&#xff1f;二、使用步骤 1.数据包套接字与多播套接字2.数据报包3.实操展示总结 前言 UDP协议程序相对于TCP协议&#xff0c;就是一个广播喇叭给全村人听和两个人说悄悄话的差别。因此UDP的数据传输效率比TCP高&#xff0c;可以同时分享给所…

《Windows PE》3.1 基本概念

在正式讲解PE文件格式之前&#xff0c;我们有必要先熟悉和PE相关的一些基本概念&#xff0c;以便于更好的理解和掌握PE文件格式。 本节必须掌握的知识点&#xff1a; 地址 指针 数据目录项 节 对齐方式 字符串编码格式 3.1.1 地址 ■在PE文件中涉及到四类地址 ●VA虚拟内存地…

【Linux】Shell 与权限:Linux 系统的双重保障

欢迎来到 CILMY23 的博客 &#x1f3c6;本篇主题为&#xff1a;Shell 与权限&#xff1a;Linux 系统的双重保障 &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Linux | 算法专题 …

三、搭建网站服务器超详细步骤——FinalShell下载安装使用流程(免费国产的SSH工具)+宝塔安装方法(分享两种安装宝塔的方法)

前言 本篇博客是搭建网站服务器模块下的第3部分 FinalShell下载安装使用流程 在分享这篇博客之前&#xff0c;首先讲一下&#xff0c;FinalShell软件是干什么用的&#xff0c;用大白话进行说明一下&#xff1a;这个软件是一款远程控制和管理服务器的软件&#xff0c;通过S…

C++字符串与整数的相互转换

文章目录 前言字符串转整数stoiisstringstreamatoi 字符转整数to_stringstringstreamsprintf ASCII码转换 前言 题目大致为&#xff1a; 给一组数据&#xff0c;去掉里面的2&#xff0c;然后再返回结果 例如&#xff1a; 输入&#xff1a;{20, 66, 521, 2024} 输出&#xff1…

手机如何切换网络IP地址:‌方法详解与操作指南‌

在当今的数字化时代&#xff0c;‌网络IP地址作为设备在网络中的唯一标识&#xff0c;‌扮演着至关重要的角色。‌对于手机用户而言&#xff0c;‌了解如何切换网络IP地址不仅有助于提升网络体验&#xff0c;‌还能在一定程度上保护个人隐私。‌本文将详细介绍手机切换网络IP地…

仿论坛项目--Kafka,构建TB级异步消息系统

阻塞队列 • BlockingQueue 解决线程通信的问题。阻塞方法&#xff1a;put、take。 • 生产者消费者模式生产者&#xff1a;产生数据的线程。消费者&#xff1a;使用数据的线程。 • 实现类ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueue、SynchronousQueue、D…