在 C/C++ 開發中,「全域變數」常被視為洪水猛獸,但若能善用靜態全域陣列或靜態區域陣列,不僅能簡化程式碼,更能避免動態記憶體分配帶來的風險。關鍵在於:擁有該陣列的任務或模組,必須具備全域生命週期——即其存活期與整個程式相同。
在多任務或多執行緒程式中,許多執行緒(如認證執行緒 thread_authenticator)擁有全域生命週期,且需要固定大小的緩衝區。若採用 malloc() 或 new 從堆疊分配,不僅增加程式碼複雜度,還得檢查回傳值、處理分配失敗、釋放記憶體,容易產生記憶體洩漏或碎片。
以下以儲存 EAP 字串的緩衝區為例:
#define MAX_PORTS 64
#define MAX_IDS (MAX_PORTS * 256)
#define MAX_MSG_LEN 4096
static char **g_aaa_eap_str_buff;
void thread_authenticator(void *_arg)
{
g_aaa_eap_str_buff = (char **)malloc(MAX_IDS);
if (!g_aaa_eap_str_buff) {
log_error("Failed to allocate buffer for storing eap strings");
return;
}
for (int i = 0; i < MAX_IDS; ++i) {
g_aaa_eap_str_buff[i] = (char *)malloc(MAX_MSG_LEN);
if (!g_aaa_eap_str_buff[i]) {
log_error("Failed to allocate buffer for storing eap strings");
}
}
while (1) { /* ... */ }
}
#define MAX_PORTS 64
#define MAX_IDS (MAX_PORTS * 256)
#define MAX_MSG_LEN 4096
static char g_aaa_eap_str_buff[MAX_IDS][MAX_MSG_LEN];
void thread_authenticator(void *_arg)
{
while (1) { /* ... */ }
}
靜態陣列的記憶體在編譯期就已分配於 .bss 或 .data 區段,完全省去 malloc() 呼叫與錯誤檢查,程式碼更清晰、執行效率更高。
若某陣列僅被單一函數(如執行緒入口函數)使用,應宣告為 static 區域陣列,將作用域限制在函數內部,進一步降低耦合與命名衝突風險。
核心原則:只要擁有者具備全域生命週期,且陣列大小在編譯期可知,優先考慮靜態陣列,拒絕不必要的動態分配。