参考文章:
https://chenqx.github.io/2014/09/25/Cpp-Memory-Management/
https://www.cnblogs.com/youxin/p/3313288.html#commentform
(1)在C++中,内存分为5个区。分别是堆,栈,自由存储区,全局/静态存储区,常量存储区。
【1】栈:在执行函数时,函数内局部变量存储单元可以在栈上创建,函数执行结束时被自动释放。栈内存分配运算内置于处理器的指令集中,效率很高,但容量有限。
【2】堆:就是那些由malloc分配的内存块,一般一个malloc对应一个free。如果程序员没有释放掉,那么在程序结束时,由操作系统自动回收。
【3】自由存储区:就是那些由new等分配的内存块,它和堆十分相似,不过它用delete来结束自己的生命。
【4】全局/静态存储区:全局变量和静态变量分配在同一个内存块中。
【5】常量存储区:分配的时常量,不允许修改。
(2)堆和栈的区别
【1】管理方式不同
对于栈,由编译器自动管理,无需我们手工控制;对于堆,释放工作由程序员操作。
【2】空间大小不同
对于堆,在32位系统下,可以达到4GB;对于栈来说,一般由一定的空间大小,可以在编译器中设置。
【3】碎片问题
对于堆来说,频繁的new/delete会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈则不会存在这个问题。
【4】生长方向不同
对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,生长方向是向下的,是向着内存地址减小的方向生长。
【5】分配方式不同
堆都是动态分配的。栈有两种分配方式,静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配;动态分配由alloca函数进行分配,栈的动态分配由编译器释放。
【6】分配效率
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定的栈的效率比较高。堆则是由C/C++函数库提供的例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
为什么栈向下增长?
与虚拟地址空间的分配规则有关,对于一个可执行的C程序,地址分配如下,从低地址到高地址依次是:text,data,bss,堆,栈,环境变量参数;其中堆和栈有很大的地址空间闲着,在需要分配内存时,堆向上长,栈向下长。
如何验证
设计两个函数,一个作为调用方,另一个作为被调用方,被调用方以一个地址作为自己的入口参数,调用方传入的地址是自己的一个局部变量的地址,然后被调用方比较这个地址和自己的一个局部变量的地址。
计算机术语----栈帧:指的就是这些与一次函数调用相关的东西,而在一个栈帧内的这些东西其相对顺序是由编译器决定的,所以,在一个栈帧内做比较,都会对编译器有所依赖。
#include<stdio.h>
void func1();
void func2(int *a);
void func1()
{
int a=0;
func2(&a);
}
void func2(int *a)
{
int b=0;
printf("%x\n%x\n",a,&b);
}
int main()
{
func1();
}
结果:
29f6ac
29f5c8