c++学习记录

目录

STL学习


1.避免使用vector<bool>

https://blog.csdn.net/haolexiao/article/details/56837445

2.在函数中定义局部函数:

https://blog.csdn.net/kof2001kop/article/details/7425186

3.malloc、linux、mmap实现

 

 

STL学习

1.string 使用

https://blog.csdn.net/qq_42659468/article/details/90381985

2.allocator:

默认是std:allocator,其他用pool_alloc比较多

3.stl库主要是用gp(generic programming)泛型编程实现的,gp是将datas和methods分开;oop是将datas和methods合并起来。

4.

 

5.operator new()和malloc()

c++中的new会调用operator new(),operator new()中会调用malloc()。c++ malloc内存的结构如下,需要用的部分越大,额外消耗占比越小

stl中的分配器分配内存(allocate)是调用的是operator new(),释放内存(deallocate)用的是operator delete()

GC2.9用的是alloc,没有用allocator。具体结构如下:

目的是为了减少额外的消耗(cookie),建立16条链表,第一个表示8个字节大小的对象,第二个表示16个字节大小的元素,容器需要的元素会缩放到8的倍数,比如50会扩展成56.

cookie上下都有,共8个字节。

6.list:是一个双向列表,一个list有一个node,node是一个list_node指针,因此一个list的对象大小是4(在gc2.9中);在4.9中,一个list有两个指针。一个list_node有两个指针和一个data.

list的iterator类对++(++i,i++),--(--i,i--)等操作符做重载。operator ++(int)是重载后置++,operator ++()是重载前置++。每个iterator有五个结构

iterator_category:iterator的分类性质

difference_type:iterator之间的距离

value_type:iterator存储的对象类型

reference:标准库中没用过

pointer:标准库中没用过

 

和 array、vector 这些容器迭代器的实现方式不同,由于 list 容器的元素并不是连续存储的,所以该容器迭代器中,必须包含一个可以指向 list 容器的指针,并且该指针还可以借助重载的 *、++、--、==、!= 等运算符,实现迭代器正确的递增、递减、取值等操作。

迭代器的移动就是通过操作节点的指针实现的

一个list:包含一个直接链表的头节点指针,该节点不存放数据。

list 容器实际上就是一个带有头节点的双向循环链表。下图为存有 2 个元素的 list 容器:

迭代器是一个模板类

http://c.biancheng.net/view/6955.html

7.Vector
扩充需要重新分配内存,两倍增长
一个vector对象有三个指针
两倍增长,先看初始大小是不是0,分配新空间,拷贝旧内容,插入新内容,插入安插点后的内容
迭代器,只需要一个指针

 

一个vector对象有三个指针:_Myfirst 指向的是 vector 容器对象的起始字节位置;_Mylast 指向当前最后一个元素的末尾字节;_myend 指向整个 vector 容器所占用内存空间的末尾字节。

在此基础上,将 3 个迭代器两两结合,还可以表达不同的含义,例如:

  • _Myfirst 和 _Mylast 可以用来表示 vector 容器中目前已被使用的内存空间;
  • _Mylast 和 _Myend 可以用来表示 vector 容器目前空闲的内存空间;
  • _Myfirst 和 _Myend 可以用表示 vector 容器的容量

迭代器是元素类型的指针

http://c.biancheng.net/view/6901.html

8.Array
就是个数组
Array要指定类型和大小,大小不为0,至少为1。是连续空间。迭代器就是个指针

9.Forward list 和list区别就是只有单向的

10.Deque
双向开口,分段串接起来,即分段连续
里面有个vector,每个元素是指针,指向一个组。
迭代器是一个class,有四个指针。cur是当前,first和last是元组的边界,node指向vector当前元组的位置。
一个deque对象有两个迭代器,一个map指针,一个size。默认一个元组存储512字节/元素大小。
操作符重载:后++调用前++
重载++   +=   --  等操作符使得看起来连续
Vector扩充时复制到新内存的中间

Queue和stack都是基于deque实现,两个都不允许遍历,不提供iterator,因为要保证先进先出或者先进后出。两个都还可以使用list作为底层实现。stack可以用vector作为底层实现,queue不可以。两个都不可以用set和map作为底层实现

 

deque:deque

容器存储数据的空间是由一段一段等长的连续空间构成,各段空间之间并不一定是连续的,可以位于在内存的不同区域

为了管理这些连续空间,deque 容器用数组(数组名假设为 map)存储着各个连续空间的首地址。也就是说,map 数组中存储的都是指针,指向那些真正用来存储数据的各个连续空间(如图 1 所示)。

deque容器的底层存储机制

通过建立 map 数组,deque 容器申请的这些分段的连续空间就能实现“整体连续”的效果。换句话说,当 deque 容器需要在头部或尾部增加存储空间时,它会申请一段新的连续空间,同时在 map 数组的开头或结尾添加指向该空间的指针,由此该空间就串接到了 deque 容器的头部或尾部。

 

迭代器是一个类,迭代器内部包含 4 个指针,它们各自的作用为:

  • cur:指向当前正在遍历的元素;
  • first:指向当前连续空间的首地址;
  • last:指向当前连续空间的末尾地址;
  • node:它是一个二级指针,用于指向 map 数组中存储的指向当前连续空间的指针。

一个deque有两个迭代器,分别是start和finish,还有一个数组指针,指向中控器map数组。start 迭代器记录着 map 数组中首个连续空间的信息,finish 迭代器记录着 map 数组中最后一个连续空间的信息。另外需要注意的是,和普通 deque 迭代器不同,start 迭代器中的 cur 指针指向的是连续空间中首个元素;而 finish 迭代器中的 cur 指针指向的是连续空间最后一个元素的下一个位置。

deque容器的底层实现

http://c.biancheng.net/view/6908.html

11.红黑树
提供迭代器,可以++和--,但不应用迭代器改变元素的值
有五个模板参数,key data 合成value,keyofvalue怎么从value去除key.compare怎么比较两个key的大小。第五个是分配器
一个rbtree有一个节点数量,一个头节点指针,一个compare函数,仿函数大小为1。共9,补充到12
Insert有insert unique和insert equal

12.set multiset
可以用迭代器遍历,但是不能通过迭代器修改。通过返回const iterator保证
Map multimap的iterator也一样,map用insert unique,multimap用insert equal

13.Map multimap
迭代器是用红黑树的迭代器,没有用const,而是在pair中将第一个设置为const。
[]重载较特殊,要让不存在的查询值返回默认值

14.Hashtable
用哈希函数选定key的位置
哈希碰撞,设计新的哈希函数,或者使用链表接起来
用链表到某个链表过长,如果元素个数比bucket个数要多,就要增加bucket的个数,重新hash.bucket的个数一般都是素数。

hashtable底层结构:

hashFcn:怎么计算出hashcode,即要放到哪个bucket

extractkey:怎么从pair里提取出key

equalkey:怎么判断两个key相等

 

迭代器是一个类

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值