運行時動態增補
關鍵區別:靜態區 (代碼、RO、RW、BSS) 由鏈接器/加載器建立;動態區 (堆、棧) 運行時隨程序行為增長縮減。
各段詳細特徵與對應 C 語言構造
| 段 | 屬性 | C 語言對應 | 示例 |
|---|---|---|---|
| 代碼段 | 只讀、可執行、可共享 | 所有函數機器碼 | int foo() { return 1; } |
| RO Data | 只讀 | const 全局/靜態、字符串常量 | const char* s = "hello"; |
| RW Data | 讀寫、已初始化 | 已初始化全局/靜態變量 | int g = 10; static int sg = 20; |
| BSS | 讀寫、未初始化、運行時清零 | 未初始化全局/靜態變量 | int arr[1000]; static int cnt; |
| 堆 | 讀寫、手動管理 | malloc/free/new/delete | int* p = malloc(100); |
| 棧 | 讀寫、自動管理、向下增長 | 局部變量、參數、返回地址 | void f(int x) { int a; } |
const char ro[] = "abc"; // RO Data (含內容) const char* ptr = "abc"; // ptr 在棟/RW/BSS,"abc" 在 RO Data char* p = "abc"; // 警告!字符串常量不可修改,應用 const char*
static 修飾全局/局部變量 → 均存放於 RW Data (已初始化) 或 BSS (未初始化)風險:遞歸過深、大對象值傳遞、大局部陣列 → 棧溢出。
char* p = malloc(100); strcpy(p, "data"); free(p); // 必須配對,否則內存洩漏 // 程序結束時 OS 回收,但長期運行服務必須嚴格管理
const char ro[] = "read only"; // RO Data
static char rw1[] = "global rw"; // RW Data
char bss1[100]; // BSS
const char* ptr_const = "constant"; // 字符串在 RO Data
int main() {
short stack_var; // 棧
char stack_arr[100]; // 棧
char stack_str[] = "stack string"; // 棧 (內容從 RO Data 複製)
static char rw2[] = "local rw"; // RW Data (局部靜態)
static char bss2[100]; // BSS (局部靜態)
static int c = 0; // RW Data
char* heap_ptr = malloc(10); // 堆
strcpy(heap_ptr, "heap"); // "heap" 在 RO Data
free(heap_ptr);
return 0;
}
printf("ro: %p\n", ro);
printf("rw1: %p\n", rw1);
printf("bss1: %p\n", bss1);
printf("stack_var: %p\n", &stack_var);
printf("heap_ptr: %p\n", heap_ptr);
觀察地址數值大小關係:代碼段 < 數據段 < 堆 < 棧 (典型 Linux x86 佈局)。