在C/C++中的變數有三種不同的storage duration(儲存週期)
- static storage duration (靜態儲存週期)
- automatic storage duration (自動儲存週期)
- heap storage duration (堆積儲存週期)
在函式外的全域變數或在函式內但是刻意以static
關鍵字修飾的變數會是屬於static storage duration。他的生命週期(lifetime)是從程式開始執行的時候開始,程式結束之後才會被釋放。整個程式運行時會佔用固定的記憶體空間。例如:
#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的變數會有以下特性:
- 如果宣告時有被初始化,其值會等於初始值。
- 如果宣告時沒有被初始化,且其型別為算術型別(arithmetic type),其值會被初始化為零。
- 如果宣告時沒有被初始化,且其型別為指標型別,其值會被初始化為
NULL
。
所以上面的g_variable1 = 0
, local_static_variable = 0
, g_variable2 = 5
。當然陣列也是a[0] = 0
, a[1] = 0
, ...a[9] = 0
。
在函式內部的變數、函式的引數(argument)如果沒有特別聲明,就是automatic storage duration。變數的生命週期始於存放變數的視野(scope)開始處,止於視野的結束處。例如:
#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的變數會有以下特性:
- 生命週期開始於宣告處,終止於所在的視野結束時。
- 每一次函式呼叫都會配置獨立的記憶體區塊。
- 除非有指明,不然所有的變數不會被初始化。
- 第三點的例外為陣列的元素如果有一個有初始值,則所有的元素都會有初始值。此時沒有指定初指值的變數會以static storage duration的方法初使化。
根據第4點,array3[2] = 0
, array3[3] = 0
,有時候我們會在宣告的後面加上= {0}
來將整個陣列初始化為0。不過要注意的是= {10}
並非把所有的元素初始化為10,只有第一個會是10,其他的都會是0。
heap dtorage duration是用於動態配置記憶體。其生命週期是在被malloc
時開始,結束於free
的時候。heap storage duration不會被初始化。例如:
#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。