# C/C++的初始化規則與變數的儲存週期 ###### tags:`code` `memory` `C` ###### 撰寫時間 : 2022/04/01 在C/C++中的變數有三種不同的storage duration(儲存週期) 1. static storage duration (靜態儲存週期) 2. automatic storage duration (自動儲存週期) 3. heap storage duration (堆積儲存週期) --- ### Static Storage Duration 在函式外的全域變數或在函式內但是刻意以`static`關鍵字修飾的變數會是屬於static storage duration。他的生命週期(lifetime)是從程式開始執行的時候開始,程式結束之後才會被釋放。整個程式運行時會佔用固定的記憶體空間。例如: ```c #include <stdlib.h> int g_variable1; /* Static Storage Duration */ int g_variable2 = 5; /* Static Storage Duration */ int g_array[10]; /* Static Storage Duration */ int main() { static int local_static_variable; /* Static Storage Duration */ return EXIT_SUCCESS; } ``` static storage duration的變數會有以下特性: 1. 如果宣告時有被初始化,其值會等於初始值。 2. 如果宣告時沒有被初始化,且其型別為算術型別(arithmetic type),其值會被**初始化為零**。 3. 如果宣告時沒有被初始化,且其型別為指標型別,其值會被**初始化為`NULL`**。 所以上面的`g_variable1 = 0`, `local_static_variable = 0`, `g_variable2 = 5`。當然陣列也是`a[0] = 0`, `a[1] = 0`, ...`a[9] = 0`。 ### Automatic Storage Duration 在函式內部的變數、函式的引數(argument)如果沒有特別聲明,就是automatic storage duration。變數的生命週期始於存放變數的視野(scope)開始處,止於視野的結束處。例如: ```c #include <stdlib.h> int main() { int variable1; /* Automatic Storage Duration */ int variable2 = 0; /* Automatic Storage Duration */ int array1[4]; /* Automatic Storage Duration */ int array2[4] = {1, 2, 3, 4}; /* Automatic Storage Duration */ int array3[4] = {1, 2}; /* Automatic Storage Duration */ { int i; /* Automatic Storage Duration */ } /* Now, "i" is dead */ return EXIT_SUCCESS; } /* Now, "variable1", "variable2", "array1", "array2" is dead. */ ``` automatic storage duration的變數會有以下特性: 1. 生命週期開始於宣告處,終止於所在的視野結束時。 2. 每一次函式呼叫都會配置獨立的記憶體區塊。 3. 除非有指明,不然所有的變數**不會被初始化**。 4. 第三點的例外為陣列的元素**如果有一個有初始值,則所有的元素都會有初始值**。此時沒有指定初指值的變數會以static storage duration的方法初使化。 根據第4點,`array3[2] = 0`, `array3[3] = 0`,有時候我們會在宣告的後面加上`= {0}`來將整個陣列初始化為0。不過要注意的是`= {10}`並非把所有的元素初始化為10,只有第一個會是10,其他的都會是0。 ### Heap Storage Duration heap storage duration是用於動態配置記憶體。其生命週期是在被`malloc`時開始,結束於`free`的時候。heap storage duration不會被初始化。例如: ```c #include <stdlib.h> int main() { int *my_array = (int *)malloc(sizeof(int) * 10); free(my_array); return EXIT_SUCCESS; } ``` 需要注意的是`my_array`這一個指標本身是屬於automatic storage duration,是`may_array`所指向的變數才是heap storage duration。 ## 參考資料 - [new 與 delete](https://openhome.cc/Gossip/CppGossip/newDelete.html) - [變數的儲存週期](https://www.ptt.cc/bbs/b97902HW/M.1226692638.A.F2B.html)