1. 程式人生 > >c/c++變數之記憶體空間分配

c/c++變數之記憶體空間分配

變數的記憶體空間主要有以下幾個:堆(heap)、棧(stack)、全域性靜態區、文字常量區、程式碼區

heap:不連續的記憶體區域,由開發者自行進行開闢和釋放。如果程式結束時沒有進行釋放、作業系統會對其進行管理。開發者通過new/malloc等建立存放在heap上的變數,通過delete/free對他們進行刪除。

stack:和堆不同,它是連續的記憶體空間。由編譯器進行分配和回收等管理。一般存放函式的引數、區域性變數等。

全域性靜態區:存放全域性變數和靜態變數。全域性變數在main方法之前宣告,不顯示使用static關鍵字。作用域是整個工程。在定義的本檔案內直接使用。而其他的檔案加上extern關鍵字聲明後,也可以使用。靜態變數由static關鍵字宣告,他的作用域只在定義的檔案,外部的檔案不能用extern的方式進行使用。也就是說全域性變數一定是靜態變數,而靜態變數不一定是全域性的。anyway,這兩個變數都儲存在全域性靜態區。

文字常量區:存放常量,像const宣告的變數、或者字串常量就儲存在這個記憶體空間中。

程式碼區:也叫程式碼段,存放程式的二進位制程式碼。

系統響應:

  對於堆,應知道系統有一個記錄空閒記憶體地址的連結串列,當系統收到程式申請時,遍歷該連結串列,尋找第一個空間大於申請空間的堆結點,刪除空閒結點連結串列中的該結點,並將該結點空間分配給程式(大多數系統會在這塊記憶體空間首地址記錄本次分配的大小,這樣delete才能正確釋放本記憶體空間,另外系統會將多餘的部分重新放入空閒連結串列中)。

  對於棧,只要棧的剩餘空間大於所申請空間,系統為程式提供記憶體,否則報異常提示棧溢位。

碎片問題:

  對於堆,頻繁的new/delete會造成大量碎片,使程式效率降低。

  對於棧,它是一個先進後出的佇列,進出一一對應,不會產生碎片。

生長方向:(這決定了棧在高地址區、堆在底地址區)

  堆向上,向高地址方向增長。

  棧向下,向低地址方向增長。

分配方式:

  堆都是動態分配(沒有靜態分配的堆)。

  棧有靜態分配和動態分配,靜態分配由編譯器完成(如區域性變數分配),動態分配由calloc函式分配,但棧的動態分配的資源由編譯器進行釋放,無需程式設計師實現。

分配效率:

  堆由C/C++函式庫提供,機制很複雜。所以堆的效率比棧低很多。

  棧是極其系統提供的資料結構,計算機在底層對棧提供支援,分配專門暫存器存放棧地址,棧操