接續前兩回內容,本文對C程序內存佈局進行系統總結,深入剖析堆棧增長方向、地址空間動態性等關鍵細節,並從虛擬內存與/proc文件系統角度拓展視野。
C程序在內存中自低地址向高地址依次分佈:
.data(已初始化全局/靜態變量)與.bss(未初始化全局/靜態變量),固定大小malloc/free),向高地址增長,程序員管理內存分區 起始地址 存放內容
棧區 0xbfde3000 la1, la2, i (局部變量)
堆區 0x0964d000 p指向的動態空間
數據區.bss 0x0804a038 ga1, static_la1 (未初始化全局/靜態)
數據區.data 0x0804a028 ga2, static_la2 (已初始化全局/靜態)
代碼區 0x080483e0 程序機器碼
實際運行地址與理論模型完全吻合,驗證了分區理論的準確性。
malloc分配越大,地址越高)| 分區 | 地址固定性 | 多次運行地址變化 |
|---|---|---|
| 代碼區 | 固定 | 不變 |
| 數據區 | 固定 | 不變 |
| 堆區 | 動態 | 每次運行不同 |
| 棧區 | 動態 | 每次運行不同 |
這解釋了為什麼全局變量地址穩定,而局部變量與動態內存地址每次運行都不同。
用戶態程序見到的地址均經過MMU映射,非物理地址。這提供了進程隔離與地址空間統一的假象。
除四大分區外,尚有:
.so/.dll)mmap)gettimeofday優化)readelf -S:查看ELF文件靜態段信息(代碼、數據區)/proc/[pid]/maps:查看進程運行時完整內存映射(含堆、棧、共享庫)/proc/[pid]/status:進程內存使用統計(VmSize, VmRSS等)$ ./program &
[1] 2736
$ cat /proc/2736/maps
...
0964d000-0966e000 rw-p 00000000 00:00 0 [heap]
bfde3000-bfe04000 rw-p 00000000 00:00 0 [stack]
...
結合變量地址即可精確判定所屬分區,如前文所示la1、la2、i落在棧區,p指向的內存落在堆區。
掌握內存佈局不僅是面試必考點,更是:
建議開發者熟練使用readelf、objdump、pmap、/proc等工具,從靜態與動態雙重視角建立立體的內存模型認知。