C 語言中定義大型全局變量(如 2MB 陣列),但編譯生成的可執行文件僅 20KB,這看似矛盾實則符合編譯器對已初始化與未初始化數據的不同處理機制。本文深入解析其底層原理。
未初始化的全局變量屬於 BSS 段,不佔用可執行文件空間;已初始化的全局變量屬於 DATA 段,會佔用文件空間。
| 類型 | 段名 | 佔用 .exe 空間 | 運行時內存 | 初始值 |
|---|---|---|---|---|
| 已初始化全局/靜態變量 | .data | 是 | 是 | 程式員指定 |
| 未初始化全局/靜態變量 | .bss | 否(僅記錄大小) | 是(OS 零初始化) | 0 / NULL |
| 局部變量 | 棧 | 否 | 運行時分配 | 未定義 |
| 動態分配 | 堆 | 否 | 運行時分配 | 未定義 |
// 情況 A:未初始化 - 不佔用 exe 空間
char buffer_a[2 * 1024 * 1024]; // .bss 段,exe 體積不變
// 情況 B:已初始化 - 佔用 exe 空間
char buffer_b[2 * 1024 * 1024] = {0, 1, 2, ...}; // .data 段,exe 體積增 ~2MB
// 情況 C:部分初始化 - 佔用 exe 空間(剩餘自動補 0)
char buffer_c[2 * 1024 * 1024] = {1}; // .data 段,exe 體積增 ~2MB
memset/迴圈)而非編譯期初始化,權衡啟動速度與文件體積此機制體現「空間換時間」的編譯器優化智慧:以運行時零初始化換取極小的可執行文件體積。