c++面经知识汇总(顺序容器、关联容器、STL的组成部分以及作用,容器删除元素导致迭代器失效)

本文深入探讨C++标准模板库(STL)的关键组件,包括map、set等容器的区别及实现原理,迭代器的操作特性,以及allocator如何高效管理内存。并对比了vector与list的不同应用场景。
请来说一下map和set的区别,分别是怎么实现的
  1. map和set都是c++的关联容器,而且其底层都是通过红黑树实现的;
  2. map中的元素是成对出现的key-value ,关键字起到索引的作用,值则表示与索引相关联的数据;set中的元素就是关键字的集合,每个元素值包含一个关键字
  3. set的迭代器是const的,不允许修改元素的值,map允许修改value但是不允许修改key,原因是因为map、set都是通过关键字来保证其有序性,
  4. map支持下标操作,set不支持下标操作,map可以用key做下标,map的下标运算符通过关键码作为下标区执行查找
STL中的allocaotr是什么

allocaotr是容器中的分配器,用来解决的是STL容器在内存管理上的底层实现细节
c++中的stl
在上面的博客已经简单的介绍了一下STL,下面详细的说一下STL中的分配器(allocaotr) ,上文已经说了他其实是为了解决STL容器在内存管理上的底层实现细节,那么STL究竟是怎样实现的呢?

首先说一下c++中STL的内存配置实现

  1. 调用库函数new,传入参数,开辟一个size_t大小的空间,返回的是这个空间的起始地址
  2. 调用构造函数,由于上一步开辟的空间是没有初始化的,因此第二步就是调用构造函数,将内存中的数据初始化
  3. 最后一步就是返回构造好的新的对象的指针
    释放:
  4. 首先是通过指针来调用类的析构函数
  5. 然后调用上面的库函数,传入的是指针的地址,然后释放对应的内存

上面说的是配置与释放,但是allocaotr觉得这样直接进行配置与释放不好,因此,它有封装了几个方法,分别是alloc::allocate()、alloc::deallocate()、::construct()、::destroy()
其中内存配置,由allocate()负责,释放由deallocate()负责,对象的构造由construct()负责,对象的析构由destory负责

同时为了提升内存管理的效率,减少申请小内存的内存碎片问题,STL又采取了两级配置器,当分配的空间大小超过128B用第一级空间配置器,小于123b用第二级。
详情可以看这篇文章
走进STL - 空间配置器,STL背后的故事

非常详细

说一说迭代器删除元素
  1. 尽量不要使用迭代器删除容器中的元素,因为这会涉及到迭代器的失效问题
  2. 对于顺序容器来说,当你使用迭代器进行删除元素,如earse(iteror) ,那么这个iteror迭代器之后的所有元素的迭代器都会失效,因为顺序容器的实现是通过连续分配的内存
  3. 对于关联容器来说,删除一个元素,并不影响其他节点(其是使用红黑树来实现的,节点之间不影响)
  4. 对于list、forword_list来说,因为其实现并不是通过连续分配的内存,所以删除也没有影响,不会令其余节点的迭代器失效
请你说一下关联迭代器数据的存放形式
  1. Map:map的底层是通过红黑树来实现的
  2. unordered_map :哈希表实现
  3. set:红黑树实现
  4. unordered_set :哈希表实现
  5. multimap:红黑树
  6. muliset:红黑树
STL的基本组成
  1. 容器 包括关联容器和顺序容器
  2. 迭代器 重载了++ == --等运算符
  3. 算法 :通过迭代器获取容器中的内容,常用的有sort\find_if等
  4. 分配器 封装了STL内存管理的底层细节
  5. 仿函数 可以自己通过lambda实现,也可以使用原有的
  6. 适配器 通过令一个对象的行为看着像另一个的行为
map与multimap的区别
  1. map映射,其中map的所有元素都是pair 同时拥有val和key。所有元素会根据key自动排序,不允许有重复的元素
  2. multimap 元素都是pair,同时拥有val和key,允许重复元素,所有的元素都会根据元素的key自动排序
vector和list的区别、应用
  1. vector是连续存储的容器,list是不连续存储的容器;
  2. vector底层是通过数组实现,list底层是通过链表实现;
  3. vector在尾部插入的速度很快,list在头尾插入速度都很快,一般是常数开销;
  4. vector删除元素的时候会导致拷贝,速度很慢,list进行删除的速度很快
  5. vector当要插入的元素大于当前的容量时,会进行扩容,而list当插入元素的时候,每次都会新开辟一段空间用来存放,删除的时候直接释放
  6. vector支持随机访问,list只能顺序访问
    应用场景:如果你需要频繁性的随机访问,而不经常性的进行插入删除使用vector,如果你经常性的插入删除,而不涉及到随机访问,使用list

下表介绍了 顺序容器

vector可变大小数组,支持随机访问,在尾部以外的位置进行插入和删除元素可能很慢
deque双端队列,支持聊苏随机发个文,在头尾位置插入/删除的速度很快
List双向量表,仅支持双向顺序访问,在list中任何位置进行插入/删除操作速度都很快
forward_list单向链表,只支持单项顺序访问,在链表任何位置进行插入删除速度都很快
array固定大小的数组,支持快速随机访问,不能添加或删除元素
string与vector相似的容器,但专门用于保存字符,随机访问快,在尾部插入删除速度很快
请说一下STL中resize和reserve的区别
  1. resize():改变的是当前容器内含有的元素数量,当使用resize(n)的时候,容器的容量变成n,如果当前的容器容量l小于n,那么会新增n-l个容量,如果l大于n那么会丢弃l-n个元素
  2. reserve :改变当前容器的最大容量,他并不会生成元素,只不过是更改了当前容器所能容纳的最大数量的对象;

注意:
容器的size是指当前已经保存对象的数量
容器的capacity则是指,在不改变容器的容量之前,容器所能容纳的最大的对象数量;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值