栈、堆、静态存储区和程序的内存布局
生活随笔
收集整理的這篇文章主要介紹了
栈、堆、静态存储区和程序的内存布局
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 棧
- 1.1 程序中的棧
- 1.2 函數調用過程
- 1.3 函數調用棧上的數據
- 2 堆
- 2.1 程序中的堆
- 2.2 系統對堆的管理方式
- 3 靜態存儲區
- 3.1 程序中的靜態存儲區
- 4 程序的內存布局
- 4.1 程序文件的一般布局
- 4.2 文件布局在內存中的映射
- 4.3 程序和進程
1 棧
棧主要用于函數調用的使用。
1.1 程序中的棧
棧的要點:
- 棧是現代計算機程序里最重要的概念之一。
- 棧在程序中用于維護函數調用上下文。
- 函數中的參數和局部變量存儲在棧上。
- 棧是一種后進先出的行為。
1.2 函數調用過程
棧保存了一個函數調用所需的維護信息: 參數、返回地址、局部變量、調用上下文、……
每次函數調用都對應著一個棧上的活動記錄:
- 調用函數的活動記錄位于棧的中部。
- 被調函數的活動記錄位于棧的頂部。
函數調用棧變化:
1.3 函數調用棧上的數據
函數調用時,對應的棧空間在函數返回前是專用的。函數調用結束時,棧空間將被釋放,數據不再有效。因此,我們不能將函數中的局部變量以指針的形式返回。
編程實驗:指向棧數據的指針
2 堆
堆主要用于內存的動態申請和歸還。
2.1 程序中的堆
關于堆:
- 堆是程序中一塊預留的空間,可由程序自由使用。
- 堆中被程序申請使用的內存在被主動釋放前將一直有效。
為什么有了棧還需要堆?
棧上的數據在函數返回后就會被釋放掉,無法傳遞到函數外部,如:局部數組。
C語言程序中通過庫函數的調用獲得堆空間
- 頭文件:malloc.h。
- malloc:以字節的方式動態申請內存。
- free:將堆空間歸還給系統。
2.2 系統對堆的管理方式
系統對堆空間的管理方式:
- 空閑鏈表法、位圖法、對象池法等等。
3 靜態存儲區
靜態存儲區用于保存全局變量和靜態變量。
3.1 程序中的靜態存儲區
靜態存儲區的要點:
- 靜態存儲區隨著程序的運行而分配空間。
- 靜態存儲區的生命周期直到程序運行結束。
- 在程序的編譯期靜態存儲區的大小就已經確定。
- 靜態存儲區主要用于保存全局變量和靜態局部變量。
- 靜態存儲區的信息最終會保存到可執行程序中。
編程實驗:靜態存儲區的驗證
#include <stdio.h>int g_v = 1;static int g_vs = 2;void f() {static int g_vl = 3;printf("%p\n", &g_vl); }int main() {printf("%p\n", &g_v);printf("%p\n", &g_vs);f();//0x804a020 0x804a024 0x804a028return 0; }4 程序的內存布局
4.1 程序文件的一般布局
不同代碼在可執行程序中的對應關系:
4.2 文件布局在內存中的映射
映射如下:
各個段的作用:
- 堆棧段在程序運行后才正式存在,是程序運行的基礎;
- .bss段存放的是未初始化的全局變量和靜態變量;
- .data段保存的是已經初始化了的全局變量和靜態變量;
- .rodata段存放程序中的常量值,如字符串常量;
- .text段存放的是程序中的可執行代碼。
程序術語的對應關系
- 靜態存儲區通常指程序中的.bss和.data段。
- 只讀存儲區通常指程序中的.rodata段。
- 局部變量所占空間為棧上的空間。
- 動態空間為堆中的空間。
- 程序可執行代碼存放于.text段。
思考:面試中的小問題
同是全局變量和靜態變量,為什么初始化和未初始化的保存在不同的段中? 從高效的角度進行思考。
4.3 程序和進程
程序與進程的不同:
- 程序是靜態的概念,表現形式為一個可執行文件。
- 進程是動態的概念,程序由操作系統加載后運行得到的。
- 每個程序可以對應多個進程。
- 每個進程只能對應一個程序。
思考:面試中的小問題
包含腳本代碼的文本文件是一種類型的可執行程序嗎?如果是,對應什么樣的進程呢?
參考資料:
總結
以上是生活随笔為你收集整理的栈、堆、静态存储区和程序的内存布局的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小花钱包查不查征信
- 下一篇: VS中查看子类对象内存分布的方法