持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情
堆和栈的区别在许多的面试中都有提及,他们的区别在计算机编程中也是属于非常基础的部分,不过我之前一直没去了解……
不过在了解之后也很简单的。
首先我们要知道程序所占的内存一共分为5大块,分别是
1、堆
2、栈
3、初始化区
4、未初始化区
5、代码区
堆——由程序员分配内存释放的,比如new指令、alloc指令和malloc指令
栈——由编译器自己分配释放的,用来存放一些参数值,局部变量的值之类的,就是除了堆和static和const以外的就都是栈了,一般编译器的栈大小是已经固定好的
借鉴一个程序代码的例子:
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456/0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456/0放在常量区,编译器可能会将它与p3所指向的"123456"
优化成一个地方。
}
a在初始化区
p1在未初始化区
b这里虽然没给他值,但是他还是占有一个随机值,字节为4,放在了栈中
s数组为字符数组,已初始化,大小为4,放在栈中
p2指针,32位计中固定占了4字节,栈中
p3指针,4字节,栈中,指向常量区中的123456/0的首字节
c 初始化区
之后是为p1、p2开辟了10和20字节的堆区域
strcpy是为p1赋值,如果进行了优化,就指向了常量区,否则就把值放入堆中
堆和栈的比较:
1、开辟方式
栈是在你定义之后直接由模拟器给你开辟的空间
例如p2,p3
堆是由程序员申请的大小,如malloc(10)就是申请10字节大小的空间
直接用new的话就是申请对象所占的字节空间
2、大小
栈是固定的常量,由模拟器决定
堆的大小为计算机系统中有效的虚拟内存容量。所以堆的容量远远的大于栈
3、存储方式
栈由于是编译器申请的,所以它所开辟的空间都是连续行的,即使在释放之后也不会产生什么碎片。
堆得位置都是随机生成的,所以他比较自由,例如链表你是没法通过简单的加上所占字节得到下一个链的位置,同时由于随机,堆会产生碎片,不过用起来比较方便
4、响应
栈的响应速度快,不过栈所申请的内存必须小于剩余空间,否则会报栈溢出
堆得响应速度偏慢,它在申请的时候会在一个空闲表找到一个堆节点大于所申请的空间,并且把这个节点分配给堆,多于的大小重新放入空闲表中
(PS:操作系统有一个记录空闲内存地址的链表)(PPS: 所谓的碎片就是空闲表中太小的空间,在两块已经被申请的空间中间并且基本上不会被用到的)
5、效率
效率嘛,不用多想,肯定是栈快
总结
堆和栈各有好坏
栈快但又不灵活而且还小
堆慢但是灵活,可分配内存大
在使用上栈比堆简单,所以若是占内存小且不是特别的扣内存的话,不妨用栈的简单