C/C++ 程序內存結構

楔子

一個可執行程序文件需要在計算機硬件上運行起來,其實質就是靜態的文件被加載到內存中的過程,可執行程序文件只是一個程序的載體。那麼執行一個應用後,它在內存中是一個怎樣的結構呢,請關注今天的走進科學——《C/C++ 程序內存結構》。

動&靜

一個程序被加載到內存中,這塊內存首先就存在兩種屬性:靜態分配內存和動態分配內存。
靜態分配內存:是在程序編譯和鏈接時就確定好的內存。
動態分配內存:是在程序加載、調入、執行的時候分配/回收的內存。

Text & Data & Bss

  • .text: 也稱爲代碼段(Code),用來存放程序執行代碼,同時也可能會包含一些常量(如一些字符串常量等)。該段內存爲靜態分配,只讀(某些架構可能允許修改)。
    這塊內存是共享的,當有多個相同進程(Process)存在時,共用同一個text段。

  • .data: 也有的地方叫GVAR(global value),用來存放程序中已經初始化的非零全局變量。靜態分配。

    • data又可分爲讀寫(RW)區域和只讀(RO)區域。
      -> RO段保存常量所以也被稱爲.constdata
      -> RW段則是普通非常全局變量,靜態變量就在其中
  • .bss: 存放程序中爲初始化的和零值全局變量。靜態分配,在程序開始時通常會被清零。

text和data段都在可執行文件中,由系統從可執行文件中加載;而bss段不在可執行文件中,由系統初始化。
這三段內存就組成了我們編寫的程序的本體,但是一個程序運行起來,還需要更多的數據和數據間的交互,否則這個程序就是死的,無用的。所以我們還需要爲更多的數據和數據交互提供一塊內存——堆棧。

堆棧(Heap& Stack)

堆和棧都是動態分配內存,兩者空間大小都是可變的。

  • Stack: 棧,存放Automatic Variables,按內存地址由高到低方向生長,其最大大小由編譯時確定,速度快,但自由性差,最大空間不大。

  • Heap: 堆,自由申請的空間,按內存地址由低到高方向生長,其大小由系統內存/虛擬內存上限決定,速度較慢,但自由性大,可用空間大。
    每個線程都會有自己的棧,但是堆空間是共用的。

Tips:

char* p = new char[20];
// 這行代碼在Heap中開闢了20個char長度的空間,同時在Stack上壓入了p,
// 指針變量p存在於棧上,其值爲剛剛在堆上開闢的空間的首地址。

圖解

sw-at 的博客上扒了一張圖,這張圖中所示內存空間,地址由下往上增長,分別標示了 .text、.data、.bss、stack和heap的內存分部情況。
我們可以看到:

  • text、data(gvar)、bss 在內存中地址較低低的位置(low level address),而堆棧則在相對較搞的位置。
  • 堆(Heap)往高地址方向生長,棧(Stack)往低地址方向生長。

memery

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章