C语言中动态区域由Stack和Heap两部分组成。简单说来,Stack由编译器自动分配释放,存放函数的参数值、局部变量等值,底层的数据结构是LIFO的栈。Heap由程序员分配释放,如果一不小心忘记了释放申请的内存,可能引起内存泄漏。Heap基于的数据结构比较复杂。
区别
申请方式
Stack由系统自动分配,存放局部变量等。 Heap由程序员调用malloc, realloc, calloc申请,并用free释放。
申请效率
Stack由系统自动分配,速度快,程序员无法控制。
Heap由程序员申请、释放,容易产生碎片,效率低于Stack。
空间大小
Stack在Linux内存区域中由高地值向低地址生长,大小固定,地址是连续的。当栈的剩余控件不足时,会提示Overflow。
Heap在内存区域中由低地址向高地址生长,是不连续的内存区域。堆的大小受制于系统有效的虚拟内存。
分配方式
Stack是连续的。只要栈的空间大于所申请的空间,系统将为程序分配空间,否则会报Overflow。
Heap收到程序申请时,操作系统有一个记录空闲内存地址的链表,会遍历该链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从空闲链表中删除,并将该节点的空间分配给程序。另外,如果找到的堆节点大小不一定正好等于申请的大小,系统会自动将多余的部分重新放入空闲链表中。反复的申请/释放,势必会生成大量的内存空间碎片,使程序效率降低。
存储内容
Stack:当函数调用时,第一个进栈的是主函数中下一条语句的地址,然后是函数的各个参数,参数是从右往左入栈的,然后是函数中的局部变量。静态变量不入栈。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后是栈顶指针所指向的、主函数中的下一条指令,程序由该点继续执行。
Heap:往往会在堆的头部用一个字节存放堆的大小,以利于free函数的释放。