在c++中,内存分为五个区,分别是栈、堆、自由存储区、全局/静态存储区、常量存储区。其中栈与堆的的区别可以从以下几点进行讨论:
管理方式不同
栈是由编译器自动管理,不需要程序员手工控制;而堆需要程序员进行释放,如果不释放即有可能发生内存泄漏。空间大小不同
能否产生碎片
频繁的new/delete的操作会造成对应内存空间的不连续,就会产生大量的碎片;而栈是先进后出队列,所以不会产生碎片问题。生长方向不同
堆的生长方向向上,及地址越来越大;栈的生长方向向下,即地址越来越小。分配方式不同
堆都是动态分配的,没有静态分配的堆;
栈有两种分配方式,可以动态分配,也可以静态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配与堆的动态分配不同,栈的动态分配是由编译器进行释放,无需程序员手工实现。分配效率不同
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。
堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系 统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就 有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。最后对堆和栈的区别进行一下总结。
堆和栈相比,由于大量 new/delete的使用,容易造成大量的内存碎片;同时,由于没有专门的系统支持,效率很低。另外堆操作可能引发用户态和核心态的切换、内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。
虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。
另外无论是堆还是栈,在使用中都要防止越界现象的发生,越界会使程序崩溃或摧毁堆栈结构,以至于产生以想不到的结果。