程序段的內存布局
在C程序中,內存通常分為幾個主要區域:
1. 代碼段(.text段) - 存放程序的指令。
2. 數據段(.data段) - 存放已初始化的全局和靜態變量。
3. BSS段(.bss段) - 存放未初始化的全局和靜態變量。
4. 堆區 - 動態分配內存(例如通過malloc)。
5. 棧區 - 存放局部變量和函數參數。
1. 局部變量
定義:局部變量是在函數或代碼塊內部聲明的變量。
存在位置:
· 棧區(Stack):局部變量存儲在程序的棧區。當一個函數被調用時,棧區會為該函數的局部變量分配內存。當函數執行結束后,這部分內存會被自動釋放。
特點:
· 作用域:局部變量只能在其聲明的函數或代碼塊內使用。外部無法訪問。
· 生命周期:局部變量的生命周期從定義時開始,到函數結束時結束。
測試程序概念圖:
2. 全局變量
定義:全局變量是在所有函數外部聲明的變量,可以被程序中任何函數訪問。
存在位置:
· 數據區(Data Segment):全局變量存儲在程序的靜態數據區(也稱為數據段)。這個區域在程序啟動時分配內存,并在整個程序運行期間保持有效。
特點:
· 作用域:全局變量可以在任何函數內訪問,任何地方都可以使用。
· 生命周期:全局變量的生命周期與整個程序的運行時間相同,直到程序結束。
測試程序概念圖:
3. 動態申請的數據
定義:動態申請的數據是指在程序運行時,根據需要動態分配內存的一種變量,通常通過如 malloc、calloc 或 new 等函數申請。
存在位置:
· 堆區(Heap):動態申請的數據存儲在堆區。堆區的內存分配和釋放由程序員手動管理。
特點:
· 作用域:動態分配的內存可以在多個函數之間共享,直到顯式釋放。
· 生命周期:生命周期由程序員控制,內存不再需要時需要手動釋放(使用 free 或 delete)以避免內存泄漏。
測試程序概念圖:
代碼測試:
結果:
查看內存映射:
內存映射解釋:
第一行 555ce2a81000-555ce2a82000 r-xp:
這個段通常是 .text 段,表示程序的代碼部分。
權限 r-xp 表明它可讀且可執行,這符合代碼段的特性。
第二行 555ce2c81000-555ce2c82000 r--p:
這里的權限為 r--p,表明這個段是可讀的,不可執行,只讀段
第三行 555ce2c82000-555ce2c83000 rw-p:
權限 rw-p 表示可讀可寫,因此這個段通常是 .bss段,用于存放未初始化的全局和靜態變量,或者是.data 段,用來存放 已初始化的全局和靜態變量。
第四行555ce460d000-555ce462e000 rw-p:
權限rw-p 表示可讀可寫,這塊有說明是heap堆區,由程序員進行分配回收
第十五行 7ffd6b3a6000-7ffd6b3c7000 rw-p:
權限rw-p 表示可讀可寫,這塊有說明是棧區
總結
由測試代碼可知雖然topo在func函數結束后在main程序還能打印,那是因為雖然釋放topo空間,但是這塊空間并沒有被占用,所以程序并沒有出錯。
所以我們根據測試記錄可得出以下結論。
這些變量的存儲位置和管理方式是理解計算機程序運行機制的基礎:
· 局部變量在棧中,具有局部作用域;
· 全局變量在數據區,具有全局作用域;
· 動態申請的數據在堆中,生命周期靈活,但需要手動管理