C 語言中宣告大型陣列(如 int c[1001][1001])若放在函式內(區域變數),會導致堆疊溢位;移至函式外(全域/靜態變數)則配置於資料段(BSS/Data),空間充足無溢位風險。
| 宣告位置 | 儲存區域 | 大小限制 | 生命週期 | 初始值 |
|---|---|---|---|---|
| 函式內(區域) | 堆疊 | 通常 1~8 MB(編譯器/OS 可調) | 函式執行期間 | 未初始化則不定值 |
| 函式外(全域) | 全域/靜態區 (.bss/.data) | 受限於虛擬記憶體,通常 GB 級 | 程式全生命週期 | 自動歸零 |
| 函式內 static | 全域/靜態區 | 同全域 | 程式全生命週期 | 自動歸零 |
| malloc/new | 堆積 | 受限於虛擬記憶體 | 手動釋放前 | 未初始化 |
// 錯誤:區域大陣列 -> Stack Overflow
void foo() {
int big[10000][10000]; // ~400 MB,遠超堆疊
}
// 正確 1:全域陣列
int big[10000][10000]; // 配置於 .bss,編譯期確定大小
void foo() { ... }
// 正確 2:動態配置(執行期決定大小)
void foo() {
int **big = malloc(10000 * sizeof(int*));
for (int i=0; i<10000; i++) big[i] = malloc(10000 * sizeof(int));
// 用完後必須 free
}
malloc/new 動態配置,記得檢查回傳值與釋放。void foo(int n) {
int arr[n][n]; // 配置於堆疊,n 過大同樣會溢位,C11 為可選特性,不建議依賴
}
理解「區域=堆疊、全域/靜態=資料段、動態=堆積」的配置規則,是寫出穩健 C 程式的關鍵。