變量存儲區:堆和棧


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

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

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

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

堆是計算機內存的一塊區域,不會自動為你管理內存,也不是由CPU嚴格管理的。它是一個更自由的內存區域(並且更大)。要在堆上分配內存,必須使用 malloccalloc,它們是內置的C函數。一旦在堆上分配了內存,你就負責在不需要它時使用 free() 釋放內存。如果沒有做到這一點,程序將會出現所謂的 內存泄漏,也就是說,堆上的內存仍被保留,但其他進程無法使用。

示例

下面這個例子展示了在棧上創建變量的情況:

#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被彈出並且消失不見。

下面是一個在堆上分配內存的例子:

#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;
}

何時使用堆?

什么時候應當使用堆,什么時候使用棧?如果你需要分配大塊內存(一個大數組,大的結構體),並且你想保持相當長的時間,此時應當使用堆。如果你只處理相對小的變量,只在函數的范圍內使用,那么使用棧,它更容易也更快。如果你需要變量類似動態大小的數組或結構體,那么應當使用堆。

參考來源

PS - 個人博客鏈接:變量存儲區:堆和棧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM