day14(map set、STL组成、迭代器、epoll、继承、右值引用、include<>""区别、malloc、内存管理)
- map和set都是根据键值排序的,所以键值不能被修改。set只有键值和元素合一,所以不允许修改元素。
- STL的allocaotr,就是分配器。用于封装STL容器在内存管理上的底层细节。
为了精密分工,分配器把new和delete两个阶段操作区分开来。
为了提高内存管理效率,减少申请小内存造成的内存碎片问题,SGI STL采用了两级配置。分配空间大于128B时直接用malloc(),realloc(),free()进行内存空间的分配和释放。小于128B时,用内存池技术,通过空间链表来管理内存。 - map存放数据的形式是红黑树,unodered_map底层结构是哈希表。
- STL组成成分,容器、迭代器、仿函数、算法、分配器、配接器。
分配器给容器分配内存空间,算法通过迭代器获取容器中的内容,仿函数可以协助算法完成各种操作,配接器用来套接适配仿函数。 - 迭代器是通过一种方法顺序访问一个聚合对象中的各个元素,而不需要知道对象内部表示,特性是与对象耦合。
迭代器不是指针,是一种类模板,模拟了指针的功能,封装了指针,相当于一种智能指针,根据对象不同的数据结构实现不同的操作。
迭代器返回的是对象的引用。 - epoll原理
- STL的resize()是改变容器的大小,vector.resize(len);容器容量变为len,生成默认元素值为0,vector.push_back()时,元素放在了末尾,即下标为len,容器容量变为len+1。
reserve(),改变容器的最大容量,不会生成元素,如果reserve后的空间比之前的大,则重新分配一个空间,并把原来的元素拷贝过来,销毁之前的内存。 - struct默认的继承权限和默认访问权限是public,而class的默认继承权限和默认访问权限是private。
- 右值引用&&,目的是:一是消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率;二是能够更简洁明确的定义泛型函数。
左值能够对表达式取地址、或具名对象/变量,一般指表达式结束后依然存在的持久对象。
右值不能对表达式取地址,或匿名对象,一般指表达式结束就不存在的临时对象。
左值可以寻址,右值不可以。左值可以被赋值,右值不可以,可以用来給左值赋值。左值可变,右值不可变。 - inculde 的双引号和<>的区别是:编译器预处理阶段查找头文件的路径不一样。
当前头文件目录(双引号独有的步骤),编译器设置的头文件目录,系统变量…指定的头文件路径。 - malloc原理,用于动态分配内存,为了减少内存碎片和系统调用的开销,其采用内存池的方式,先申请大块内存作为堆区,然后将堆区分为多个内存块,以块做为内存管理的基本单位。
采用是隐式链表结构将堆区分成连续的、大小不一的快。采用显式链表结构来管理所有的空闲块。
每次内存分配的时候隐式遍历所有空闲块,选择满足需求的块进行分配。
malloc在申请内存的时候,一般会通过brk或者mmap系统调用的申请。其中当申请内存小于128k时会使用系统函数brk在堆区中分配,而当申请大于128k时,会使用系统函数mmap在映射区分配。 - C++内存管理方式:(内存结构)
虚拟内存分为:代码段、数据段、BSS段、堆区、文件映射区、以及栈区六个部分。
代码段包括只读存储区和文本区,其中只读存储区存储字符串常量,文本存储程序的机器代码。
数据段存储程序中已经初始化的全局变量和静态变量。
bss段存储未初始化的全局变量和静态变量(全局+局部),以及所有被初始化为0的全局和静态变量。
堆区调用new/malloc函数时在堆区动态分配内存,同时需要调用delete/free来手动释放申请的内存。
映射区存储动态链接库以及调用mmap函数进行的文件映射。
栈使用栈空间存储函数的返回地址、参数、局部变量、返回值。