畢竟我本身並不是CS出身,所以程式相關課程所學不多,大部分是自己網路上找。這次想跟大家談的內容是有關C++變數的存放位置。或許你會覺得只要宣告正確編譯過了就沒事,何需在意他的變數存放位置? 可是自從某天在網路上看到相關文章,讀懂之後會有一茅塞頓開的感覺。
_________
| stack |
| heap |
|_________|
| .data |
|_________|
| .text |
|_________|
(之後補圖)
在程式執行過程中,處理器會幫我們分配一塊記憶體如上圖。這記憶體分為四大塊,會一直變動的stack 與 heap ,與固定不變的.data 與 .text
stack
區域變數(non-static)都會放在這裡,他會隨著function被call的順序一層一層"堆疊",所以每進入或離開一個scope,stack的堆疊方式就會依序改變。
有幾個東西要稍微提醒一下!
- stack他的資料處理型態是先進後出First-in, Last-out(FILO)。
- 由於區域變數指在此function被宣告,所以有作用域(scope)的限制,離開就消失,沒有特別宣告其他型態不可以被其他人所使用。
- 如果你有使用過GDB相關的debug軟體,當你發現bug時,程式它是一層一層被call進去,所以你在除錯時,你會一層一層往外看。你可以從他所提供的資訊感受到你function call進去的意思,有一種在剝洋蔥的感覺。
void f(){
int i; //non-stack var. (in stack)
static int i; //stack var. (in .data)
}
heap
這區塊裡的記憶體會隨著程式的執行而有所增減,主要存被"new"出來的動態變數。因為是user所要求的記憶體,程式會回傳一個指摽,所以回收的動作要自行處理,所以我們才說"自己new的記憶體自己delete!!!"
通常記憶體被delete之後會再讓該指標指向NULL(第0塊位置),這是為了讓系統之後可以回收此記憶體,就算記憶體被delete之後,指標依舊可以指向他。
new 有兩步驟
1. Memory allocation: 向 heap 要一塊記憶體
2. Initialization : 初始化,呼叫constructor
delete 也有兩步驟
1. clean up : 呼叫 deconstructor 清空記憶體
2. free : 歸回記憶體
如果呼叫 deconstructor 卻沒有歸還記憶體,之後delete 還要把指標指向NULL ,有關於C++的new/delete之後會再攥寫一篇敘述,在此就先打住。
.data
這塊區域主要存放Global跟static variable,此區塊的物件可以被任何地方存取,這塊記憶體會固定且一開始就規劃好。
.text
主要是存放程式碼的地方
來看看以下這個例子
void f(){
int* pa=new int;
}
所以記憶體他怎配置呢?
首先,pa是由我們宣告出來的"區域變數",所以pa會存放在stack (因為它是個區域變數),而我們new的是int,所以它存放在heap裡,透過指標把pa指過去heap裡的int。