最近在看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-我的博客連接:變量存儲區:堆和棧內存