堆和栈(都是虚拟空间)
1,变量:局部变量存储在栈中,生命周期结束后,由系统释放。对于函数中没有初始化的变量是不会分配空间的,并且变量被分配栈的位置和变量初始化顺序相反。如果是数组,下标越大地址越高。
2,参数:函数参数是存入栈中的,如果参数是表达式,那么一定要先计算出表达式的值,然后再入栈。(真正的编译器实际上会使用寄存器来传递参数,超过一定值再使用栈)。
3,SP和BP:编译器为调用函数自动分配栈空间,程序的栈空间有栈顶指针寄存器(SP),它所指向的栈顶是目前所能分配栈空间的极限,当栈空间不够用的时候,就需要往低地址移动该指针,分配更多的栈空间。
函数从调用到结束的过程:1,先将原始BP入栈 2,将BP付给SP 3,S对SP进行减操作,开辟空间 4 函数逻辑运行 5出栈恢复BP(rbp) 6 返回,转交控制权。Trick现象!
堆
1,堆是动态存储区,是在程序运行时分配。Malloc和new都是在堆上操作,需要free/delete手动释放。对于new出数组类型要用delete[]
分配策略:首次适配、循环首次适配、最佳匹配、最差匹配、伙伴算法、slab层
关于堆的释放问题就要比栈的释放更加复杂,我们使用malloc时候指定分配的长度并返回首地址,但是free的时候仅仅传递了首地址,free是如何知道要释放多大内存。一个简单实现策略:在堆分配内存的时候,通常会比需要的多分配一点些,用一部分来存取偏移量,作为首部。这样free的时候先读取首部就知道释放多少了。
Malloc 和new 的区别
1,分配内存的位置,new分配在自由存储区(抽象概念,既可以是堆区,也可以是静态存储区,这取决于new的具体实现),而malloc分配在堆区。
2,分配的内存大小,new,编译器根据数据的类型计算得出,而malloc要显示指定字节数
3,返回值不同,new分配成功返回相应类型的指针,而maloc返回void指针
如果分配失败,new会抛出异常(try catch 用法 bad_alloc),而malloc返回NULL
4,new是C++的运算符,而malloc是库函数。
5,new允许重载
6,new/delete会调用构造函数和析构函数,malloc不会。
7,对数组的处理,有new[] 来处理数组,而malloc需要计算数组所需要的空间。
8,malloc,可以使用relloc重新分配内存的大小,new不可以
扩容原理:
Relloc先判断当前指针所指内存是否有足够的连续空间,1如果有原地扩大可分配的内存地址,并返回原来的指针. 2如果空间不够,先按照指定大小分配空间,将原有数据拷贝到新的内存区域,然后释放原来的内存。
9如果不够,可以继续谈谈new malloc 实现原理,空闲链表 分配方法(几个适配原则)
Delete和free的实现原理,free为什么知道销毁多大空间?
New :1,分配空间 2构造对象
Malloc:系统将可用的内存块连接为一个空闲链表。调用malloc函数时,它沿着链表寻找合适大小的内存块,将内存块一分为二,一块分配给用户,剩下的返回到空闲链表上。如果,用户申请了一个较大的内存,空闲链表上的内存片段无法满足,那么malloc函数会将各个内存片段进行整理,将相邻的内存块合成较大的内存块。
Free函数将用户释放的内存块连接到空闲链表上。
学会延伸扩展:伙伴算法、slab层