1. 程式人生 > >c語言五大記憶體分割槽-(堆,棧,全域性/靜態儲存區,自由儲存區,程式碼區)與可執行程式的三段-(Text段,Date段,Bss段)

c語言五大記憶體分割槽-(堆,棧,全域性/靜態儲存區,自由儲存區,程式碼區)與可執行程式的三段-(Text段,Date段,Bss段)

一、c語言五大記憶體分割槽

  1. 棧區(stack):存放函式形參和區域性變數(auto型別),由編譯器自動分配和釋放
  2. 堆區(heap):該區由程式設計師申請後使用,需要手動釋放否則會造成記憶體洩漏。如果程式設計師沒有手動釋放,那麼程式結束時可能由OS回收。
  3. 全域性/靜態儲存區:存放全域性變數和靜態變數(包括靜態全域性變數與靜態區域性變數),初始化的全域性變數和靜態區域性變數放在一塊,未初始化的放在另一塊
  4. 文字常量區:常量在統一執行被建立,常量區的記憶體是隻讀的,程式結束後由系統釋放。
  5. 程式程式碼區:存放程式的二進位制程式碼,記憶體由系統管理

 



 二、可執行程式程式三段-Text段,Date段,Bss段

                   

   1.一個程式的3個基本段:text段,dtae段,bss段

  • text段在記憶體中被對映為只讀,但date段與bss段是可寫的
  • text段:程式碼段,就是放程式程式碼的,編譯時確定,只讀
  • date段:存放在編譯階段(而非執行時)就能確定的資料,可讀可寫。也就是通常所說的靜態儲存區,賦了初值的全域性變數和賦初值的靜態變數存放在這個區域,常量也存在這個區域
  • bss段:已經定義但沒賦初值的全域性變數和靜態變數存放在這個區域。



 

兩者之間區別是:程式碼段,資料段,堆疊段是cpu級別的概念,五大分割槽屬於語言級別的概念,兩者是不同的概念。

 




 

三、可執行程式記憶體空間與邏輯地址空間的對映與劃分

                               

  • 左邊是UNIX系統的執行檔案,右邊是程序對應的邏輯地址空間的劃分情況
    • 首先是棧區(堆疊區stack),堆疊是由編譯器自動分配釋放,存放函式的引數和區域性變數的值(auto型別),操作方式類似於資料結構中的棧。棧的申請是由系統自動分配,如在函式內部申請一個區域性變數int h,同時判斷所申請空間是否小於棧的剩餘空間,如果小於則為其開闢空間,為程式提供記憶體,否則將報異常提示棧溢位。
    • 堆(heap),堆一般由程式設計師分配釋放,若程式設計師不釋放,程式結束可能由OS回收。它與資料結構中的堆是兩回事,分配方式類似於連結串列,申請則是程式設計師自己操作使用malloc或new。申請過程比較複雜,當系統收到程式的申請時,會遍歷記錄空閒記憶體地址的連結串列,以求尋找第一個空間大於所申請空間的堆節點,然後將該節點從空閒節點連結串列中刪除,並將該節點的空間分配給程式,有些情況下,新申請的記憶體塊的首地址記錄本次分配的記憶體塊的大小,這樣在delete尤其是delete[]時能正確的釋放記憶體空間。
    • 下邊是全域性靜態儲存區,全域性變數與靜態變數的儲存是放在一塊的,初始化的全域性變數與靜態變數存放在一塊區域,未初始化的全域性變數與未初始化的靜態變數存放在相鄰的另一塊區域。
    • 文字常量區,常量字串就是放在該部分,只讀儲存區,程式結束後由系統釋放
    • 程式程式碼區,存放程式的二進位制程式碼區。