日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

栈、堆、静态存储区和程序的内存布局

發布時間:2025/4/5 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 栈、堆、静态存储区和程序的内存布局 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 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 函數調用棧上的數據

函數調用時,對應的棧空間在函數返回前是專用的。函數調用結束時,棧空間將被釋放,數據不再有效。因此,我們不能將函數中的局部變量以指針的形式返回。


編程實驗:指向棧數據的指針

#include<stdio.h>int* g(void) {int a[10] = {0};return a; }void f() {int i = 0;int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};int *a = g();/*for (i=0; i<10; i++){b[i] = a[i];} //不注釋掉能正常訪問b的值*/for (i=0; i<10; i++){printf("%d.\n", b[i]);//直接打印,由于調用了printf函數,會建立相應的活動記錄,從而該變b的值} }int main(void) { f(); return 0; }

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 程序和進程

程序與進程的不同:

  • 程序是靜態的概念,表現形式為一個可執行文件。
  • 進程是動態的概念,程序由操作系統加載后運行得到的。
  • 每個程序可以對應多個進程。
  • 每個進程只能對應一個程序。

思考:面試中的小問題
包含腳本代碼的文本文件是一種類型的可執行程序嗎?如果是,對應什么樣的進程呢?


參考資料:

  • C語言進階剖析教程
  • 總結

    以上是生活随笔為你收集整理的栈、堆、静态存储区和程序的内存布局的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。