c++面经知识汇总(顺序容器、关联容器、STL的组成部分以及作用,容器删除元素导致迭代器失效)
发布日期:2021-05-07 17:59:56 浏览次数:30 分类:精选文章

本文共 2381 字,大约阅读时间需要 7 分钟。

请来说一下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容器在内存管理上的底层实现细节

在上面的博客已经简单的介绍了一下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用第二级。

详情可以看这篇文章
非常详细

说一说迭代器删除元素
  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则是指,在不改变容器的容量之前,容器所能容纳的最大的对象数量;

上一篇:c++面经知识汇总(STL中迭代器的作用、类成员的访问权限、struct和class的区别,类中定义应用数据成员)
下一篇:c++面经知识汇总(虚函数怎样实现多态、函数调用、处理函数返回值、malloc和new的区别)

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2025年04月18日 02时25分28秒