最近在看PHP源码解析,涉及到堆栈存储区的知识,而我对于这个却不太清楚,所以,看了一下相关资料,总结一下。html
栈,存储函数中的局部变量(临时变量),存储函数地址,栈是后进先出的结构,由CPU管理和优化。数组
使用栈存储变量的优点在于:你不用再管理内存了,没必要手动分配内存或释放它,此外,因为CPU相关的优化,读取写入的效率也很高。函数
关于栈须要注意的一点是:存储在栈上的变量的大小是有限制的,而堆却不是。优化
堆是计算机内存的一块区域,不会自动为你管理内存,也不是由CPU严格管理的。它是一个更自由的内存区域(而且更大)。要在堆上分配内存,必须使用 malloc
或 calloc
,它们是内置的C函数。一旦在堆上分配了内存,你就负责在不须要它时使用 free()
释放内存。若是没有作到这一点,程序将会出现所谓的 内存泄漏,也就是说,堆上的内存仍被保留,但其余进程没法使用。code
下面这个例子展现了在栈上建立变量的状况:htm
#include <stdio.h> double multiplyByTwo (double input) { double twice = input * 2.0; return twice; } int main (int argc, char *argv[]) { int age = 30; double salary = 12345.67; double myList[3] = {1.2, 2.3, 3.4}; printf("double your salary is %.3f\n", multiplyByTwo(salary)); return 0; }
第10,11,12行建立了变量:int、double和double数组。这些变量被推入栈中,当main退出时,这些变量自动从栈中弹出。相似的,函数multiplyByTwo()中的twice变量被推入栈中(当multiplyByTwo()被调用时),当multiplyByTwo()退出时,twice被弹出而且消失不见。blog
下面是一个在堆上分配内存的例子:进程
#include <stdio.h> #include <stdlib.h> double *multiplyByTwo (double *input) { double *twice = malloc(sizeof(double)); *twice = *input * 2.0; return twice; } int main (int argc, char *argv[]) { int *age = malloc(sizeof(int)); *age = 30; double *salary = malloc(sizeof(double)); *salary = 12345.67; double *myList = malloc(3 * sizeof(double)); myList[0] = 1.2; myList[1] = 2.3; myList[2] = 3.4; double *twiceSalary = multiplyByTwo(salary); printf("double your salary is %.3f\n", *twiceSalary); free(age); free(salary); free(myList); free(twiceSalary); return 0; }
何时应当使用堆,何时使用栈?若是你须要分配大块内存(一个大数组,大的结构体),而且你想保持至关长的时间,此时应当使用堆。若是你只处理相对小的变量,只在函数的范围内使用,那么使用栈,它更容易也更快。若是你须要变量相似动态大小的数组或结构体,那么应当使用堆。ip
PS-我的博客连接:变量存储区:堆和栈内存