全局內存強調的是生命周期而非作用域。static 修飾的局部變量、嵌入式系統中的堆實現(大數組二次分配)均屬全局內存範疇。ELF 可執行文件中,全局內存分為 BSS、Data、Rodata 三段,理解其特性是時空優化關鍵。
| 段 | 含義 | 文件佔用 | 運行時佔用 | 初始化 | 典型用途 |
|---|---|---|---|---|---|
| BSS | Block Started by Symbol | 否 | 是 | OS 載入時清零 | 大數組、零初始化結構體 |
| Data | 已初始化非零數據 | 是 | 是 | 程序員顯式初始化 | 配置參數、非零常量 |
| Rodata | 只讀數據 | 是 | 是(只讀頁) | const 修飾、字符串字面量 | 常量表、格式化字符串 |
int bss_array[1024 * 1024] = {0}; // 4MB
int main() { return 0; }
$ gcc -g bss.c -o bss.exe $ ll -rwxr-xr-x 1 root root 5683 // 僅 5KB!
結論:BSS 僅記錄大小,OS 載入時分配並清零。雖然 OS 會清零,但為可移植性建議顯式初始化。
int data_array[1024 * 1024] = {1}; // 非零初始化
$ gcc -g data.c -o data.exe $ ll -rwxr-xr-x 1 root root 4200025 // 4MB+!
結論:非零初始化數據必須存入文件,載入時映射到內存。
| 修飾對象 | 作用 | 內存段 |
|---|---|---|
| 局部變量 | 改變生命周期 → 全局 | BSS/Data |
| 全局變量/函數 | 限制作用域 → 文件內可見 | BSS/Data/Rodata |
| inline 函數 | 限制作用域 | .text |
const char* p = "abc"; // 指針常量:p 可變,*p 不可變
char* const p = "abc"; // 常量指針:p 不可變,*p 可變
const char* const p = "abc"; // 雙重常量
字符串字面量默認 const,存儲在 Rodata。
static int arr[1000000] = {0}; 進 BSS,不增大二進制const struct config_table 進 Rodata,多進程共享、可 XIPconst 利用 NorFlash/Rom,節省寶貴 RAM全局內存三段各有千秋:BSS 省文件空間,Data 攜帶初始值,Rodata 共享只讀、硬件保護。善用 static/const/volatile,讓編譯器幫你把數據放對地方,是 C 語言工程優化的基本功。