| 區域 | 存放內容 | 生命週期 | 管理方式 |
|---|---|---|---|
常數區 .rodata | 字串常量、const 修飾的全域變數 | 程式全程 | 唯讀,寫入觸發 SegFault |
靜態區 .data/.bss | 全域變數、static 變數(含區域 static) | 程式全程 | 編譯期定址,.data 有初值,.bss 零初始化 |
| 堆疊 | 區域變數、函數參數、返回位址 | 函數呼叫期間 | 編譯器自動配置/釋放,向下增長 |
| 堆區 | malloc/free/new/delete 動態記憶體 | 手動管理 | 程式員負責,忘釋放造成洩漏 |
char *p = "hello":p 在堆疊,"hello" 在 .rodata,嘗試 p[0]='H' 會崩潰char a[] = "hello":字串常量作為陣列初始化值,編譯器將字元直接嵌入指令碼區初始化陣列,a 在堆疊,**不佔用常數區**const int g = 10(全域)→ .rodata;const int l = 10(區域)→ 堆疊,仍可透過指標修改(C 與 C++ 行為不同).data vs .bssint g = 5 → .data(映像檔佔空間)int g 或 static int g = 0 → .bss(映像檔僅記錄大小,載入時清零)static 修飾全域 → 僅本檔可見(內部連結);修飾區域 → 僅函數可見,但儲存於靜態區int a=0, b=0; int arr[5]={1,2,3,4,5};
printf("%p %p %p", &a, &b, arr);
// &a > &b > arr[0] 先宣告位址較高
// arr[0] < arr[1] < ... 陣列元素位址遞增
// 系統按「最大成員大小」成批配置堆疊空間,造成間隙
char *p = "readonly"; p[0] = 'w'; // SIGSEGV const int *q = malloc(4); *q = 5; // OK,指標指向堆區
原文出處:淺談 C 語言的資料存儲(一)、(二)