1. 程式人生 > >C之內存布局(三十六)

C之內存布局(三十六)

C語言 內存布局 .text .bss .data

我們在上節中說到了棧區、堆區以及靜態存儲區,那麽我們來看看在程序文件的一般布局。我們先來看看不同代碼在可執行程序中的對應關系,如下圖所示

技術分享圖片

我們看到程序中的經過初始化的全局變量和加 static 修飾的初始化過後的局部變量都放在 .data 段,未經初始化的全局變量和加 static 修飾的局部變量都放在 .bss 段,函數和函數調用都放在 .text 段。

我們下來看看程序和進程的區別,程序是靜態的概念表現為一個可執行文件,而進程是動圖的概念,程序由操作系統加載運行後得到進程。每個程序可以對應多個進程,但是每個進程只能對應一個程序。我們舉例來說,一個瀏覽器就相當於是程序,它沒運行就沒有對應的進程。但是我們可以同時多次打開同一個瀏覽器,這時每個打開的瀏覽器就相當於是一個進程。

我們在面試中有時會遇到這樣的問題:包含腳本代碼的文本文件是一種類型的可執行程序嗎?如果是,它對應什麽樣的進程呢?我們想的是腳本程序嘛,就肯定能直接運行哈,那它會對應什麽樣的進程呢?不知所雲了。哈哈,我們來看看一般的可執行程序和腳本文件的區別,如下圖所示

技術分享圖片

我們看到可執行程序是由操作系統直接加載的,便直接對應了一個進程。但是我們運行腳本文件之後,那麽操作系統中會有對應的腳本解釋程序,經腳本解釋程序執行後,便產生對應的進程,這個進程反過來讀取並解釋執行腳本。這樣腳本文件就得到運行啦。

下來我們來看看文件布局在內存中的映射

技術分享圖片

我們看到可執行程序 a.out 中分為頭文件、.text、.data 以及 .bss 段

。對應在進程中便去掉了頭文件而加上了棧和堆。那麽我們接下來講講各個段的作用,堆棧段在程序運行後才正式存在,是程序運行的基礎; .bss 段存放的是未初始化的全局變量和靜態變量; .text 段存放的是程序中的可執行代碼; .data 段保存的是已經初始化了的全局變量和靜態變量; .rodata 段存放程序中的常量值,如字符串常量。

靜態存儲區通常指程序中的 .bss 和 .data 段;只讀存儲區通常指程序中的 .rodata 段;局部變量所占空間為棧上的空間;動態空間為堆中的空間;程序可執行代碼存放於 .text 段。

那麽我們想下,同是全局變量和靜態變量,為什麽初始化的和未初始化的需要保存在不同段中呢?通常在編譯器中,沒有初始化的變量,我們都要初始化為 0,如果我們一個一個的去檢查,是不是效率就很低呢?如果我們分開存放,那麽那些已經初始化過的變量就不用去檢查了,從而效率會變高。

通過對程序文件中內存布局的學習,總結如下:1、程序源碼在編譯後對應可執行程序中的不同存儲區;2、程序和進程不同,程序是靜態概念,進程是動圖概念;3、堆棧段是程序運行的基礎,只存在於進程空間中;4、程序可執行代碼存放於 .text 段,是只讀的;5、.bss 和 .data 段用於保存全局變量和靜態變量。


歡迎大家一起來學習 C 語言,可以加我QQ:243343083

C之內存布局(三十六)