堆和栈的区别
(1)管理方式不同:
stack:系统自动分配释放,如声明int a;系统自动在栈区为变量开辟空间
heap:程序员申请释放,容易产生内存泄漏,并指明大小,c中malloc,如char *p = (char *)malloc(10);//10个字节
C++中的new操作符,int p2=new int(10);//4个字节的int型
注意:p和p2本身是在栈中,但他们指向的地址是堆空间。
(2)空间大小不同:
每个进程拥有的栈的大小要远远小于堆的大小。理论上,程序员可以申请的堆的大小为虚拟内存的大小,进程栈的大小64位windows默认是1M,64位的linux默认10M。
(3)生成方向不同:
堆的生长方向向上,内存地址由低到高。栈的生长方向向下,内存地址由高到低。
(4)分配方式不同:
堆都是动态分配的,没有静态分配的堆。栈有两种分配方式:静态分配和动态分配。静态分配由操作系统完成,比如局部变量的分配。动态分配由alloc函数进行分配,但是栈的动态分配和堆不同,它的动态分配是由操作系统进行释放,无需我们手工实现。
(5)分配效率不同:
栈是由系统自动分配,会在硬件层级对栈提供支持,分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制比较复杂,频繁的内存申请容易产生内存碎片。显然堆的效率要比栈低很多。
(6)存放内容的不同:
栈存放的内容:函数返回的地址(p1 = (char)malloc(10);p1就是栈上的),相关参数
(fun(int a)),局部变量,寄存器内容等。堆一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中内容是由程序员来填充的。
小结:
可以看出大量使用malloc()/free()或new/delete容易产生内存碎片和内存泄漏,效率较低。栈的应用比较广泛,函数的调用过程由栈来实现,函数返回地址、EBP、实参和局部变量都采用栈的方式存放。但是大量申请内存空间时,还是要用栈