您的位置:首页 > 其它

基础——堆和栈的区别

2015-11-23 20:58 225 查看
堆和栈的区别在许多的面试中都有提及,他们的区别在计算机编程中也是属于非常基础的部分,不过我之前一直没去了解……

不过在了解之后也很简单的。

首先我们要知道程序所占的内存一共分为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、效率

效率嘛,不用多想,肯定是栈快

总结

堆和栈各有好坏

栈快但又不灵活而且还小

堆慢但是灵活,可分配内存大

在使用上栈比堆简单,所以若是占内存小且不是特别的扣内存的话,不妨用栈的简单
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: