變量存儲區:堆和棧

最近在看PHP源碼解析,涉及到堆棧存儲區的知識,而我對於這個卻不太清楚,所以,看了一下相關資料,總結一下。html

棧,存儲函數中的局部變量(臨時變量),存儲函數地址,棧是後進先出的結構,由CPU管理和優化。數組

使用棧存儲變量的優點在於:你不用再管理內存了,沒必要手動分配內存或釋放它,此外,因爲CPU相關的優化,讀取寫入的效率也很高。函數

關於棧須要注意的一點是:存儲在棧上的變量的大小是有限制的,而堆卻不是。優化

堆是計算機內存的一塊區域,不會自動爲你管理內存,也不是由CPU嚴格管理的。它是一個更自由的內存區域(而且更大)。要在堆上分配內存,必須使用 malloccalloc,它們是內置的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-我的博客連接:變量存儲區:堆和棧內存

相關文章
相關標籤/搜索