首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言變數記憶體佈局全景圖:數據段、棧、堆、代碼段、BSS段深度解析

     編輯:C 語言問答

進程虛擬位址空間佈局 (典型 Linux x86-64)

高位址
+------------------------+
|  栈 - 向下增長         |  局部變數、函式參數、返回位址、暫存器保存、alloca
|       ...              |
|       ↓                |
|                        |
|       ↑                |
|       ...              |
|  堆 - 向上增長         |  malloc/free/new/delete、動態分配、brk/mmap
+------------------------+
|  BSS 段                |  未初始化全域/靜態變數、零初始化、編譯器分配大小、不佔檔案空間
+------------------------+
|  數據段                |  已初始化全域/靜態變數 (非零)、const 全域 (視架構)、編譯時確定大小、佔檔案空間
+------------------------+
|  只讀數據段            |  字串字面值、const 全域 (部分架構)、vtable、只讀表
+------------------------+
|  代碼段                |  機器指令、函式體、常數池、只讀、可共享
+------------------------+
低位址

各段詳細特性

段存放內容生命週期權限典型大小分配方式
代碼段函式機器碼、字串字面值、只讀常數程式運行全程R-X (可讀可執行)固定連結器分配
只讀數據const 全域、vtable、跳轉表程式運行全程R--固定連結器分配
數據段已初始化全域/靜態變數 (int g=10;)程式運行全程RW-固定連結器分配,載入時從映像檔複製
BSS段未初始化全域/靜態變數 (int g; static int s;)程式運行全程RW-固定載入器清零,不佔映像檔空間
堆動態分配記憶體 (malloc/free/new/delete)手動管理RW-動態增長分配器管理 (brk/mmap)
棧局部變數、參數、返回位址、暫存器溢出、VLA、alloca函式呼叫期間RW- (通常設不可執行 NX)動態增長 (預設 8MiB Linux, 1MiB Windows)編譯器生成序言/尾聲自動管理

常見錯誤與排查

  • 棧溢位: 遞迴過深、大型 VLA/局部陣列、alloca 過大 → `Segmentation fault`。改用堆分配或增大棧 (`ulimit -s`, `/F` 編譯選項)。
  • 堆破壞: 緩衝區溢出、雙重釋放、使用已釋放記憶體、釋放非堆指標 → 行為未定義。使用 AddressSanitizer (`-fsanitize=address`)、Valgrind 檢測。
  • 全域變數初始化順序: 不同編譯單元全域變數初始化順序未定義 → 依賴順序的邏輯錯誤。使用「構造時首次使用」模式 (函式靜態局部變數) 解決。
  • 字串字面值修改: `char *p = "hello"; p[0] = 'H';` → 崩潰 (寫入只讀段)。改用 `char p[] = "hello";` 或 `char *p = strdup("hello");`。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved