一起talk C栗子吧(第一百三十一回:C語言實例--C程序內存布局三)
各位看官們,大家好。上一回中咱們說的是C程序內存布局的樣例,這一回咱們繼續說該樣例。閑話休提,言歸正轉。讓我們一起talk C栗子吧。
看官們,關於C程序內存布局的樣例,我們在前面的兩個章回都介紹過了,這一回我們將對前面章回中的內容進行總結和提示。
內存布局總結
C程序的內存布局主要有四個分區:代碼區,數據區(data和bss)。堆區和棧區。能夠使用readelf -S filename查看各個分區的內存地址。這四個分區在內存中從低地址空間開始依次向高地址延伸。我們再次使用前面章回中的圖直觀地展示給大家,而且對這些分區做一個全面的總結。
- 代碼區:主要存放程序的代碼。位於內存的低地址空間中。
- 數據區:它的地址空間位於代碼區上面。主要存放程序中的變量,只是函數中的局部非靜態變量不在該區域中,而是在棧區中。關於變量的類型不同。存放的區域也不同,更加具體的劃分。請參考以下data和bss相關的信息。
- data:主要存放程序中初始化的全局變量和局部靜態變量。
當中全局變量不用區分靜態和非靜態。僅僅要是全局變量都在該區域中。
- bss:主要存放程序中未初始化的全局變量和局部靜態變量。
當中全局變量不用區分靜態和非靜態,僅僅要是全局變量都在該區域中。
- 堆區:位於數據區上面。堆區的大小不固定,它主要存放程序中動態分配的內存。該區域的分配和回收由程序猿自己控制。因此也easy出問題。
- 棧區:位於堆區上面,棧區的大小也不固定。它主要存放函數中的局部非靜態變量和函數調用相關的信息。該區域由系統進行管理,程序猿不能控制。
總結完分區的內容後。我們結合前面章回中的樣例,總結一下樣例中各個變量在內存中的分布信息,大家從中能夠看到,樣例中各個變量在內存中的分布和我們上面總結的內容全然一致。
內存分區 分區起始地址 分區中存放的變量和代碼
棧區: 0xbfde3000 存放函數和局部變量:la1,la2,i
堆區: 0x0964d000 存放動態分配的內存空間:p所指向的空間.
數據區中的bss區: 0x0804a038 存放程序中未初始化的全局變量和局部靜態變量:ga1,static_la1
數據區中data 區: 0x0804a028 存放程序中初始化的全局變量和局部靜態變量:ga2,static_la2
代碼區: 0x080483e0 存放程序的代碼
內存布局細節
除了總結外,我們另一些小的細節須要共享給大家。
希望引起大家的註意:
- 1.在內存布局圖中堆區和棧區的分界處各有一條綠線。它表示堆區和棧區的大小是在變化的,它們不像代碼區和數據區一樣擁有固定的大小。
- 2.堆區的內存空間是從低地址向高地址延伸,而棧區的內存空間是從高地址向低地址延伸。雖然它們都是大小能夠變化的分區。可是在分區變化的方向上正好相反。
- 3.程序中代碼區和數據區的地址空間是固定的。不會隨著程序執行而發生變化。
可是程序中堆區和棧區的地址空間是動態變化的。已經有細心的看官發現了,我們在上一回中的樣例,執行過兩次。位於數據區中的變量地址在兩次執行結果中全然一致,可是位於堆區和棧區中的變量地址在兩次執行結果中不同樣。
這便是最好的證明。
內存布局之外
看官們,俗話說的好,當局者迷。旁觀者清。在大家細致觀察內存中的各個分區時。讓我們跳出這些分區之外,從整個內存的角度來做一些說明,希望能把大家就“迷局”中拉出來 。
- 1.我們在這些章回中說的地址都是指虛擬內存地址,這點在一百二十九回介紹過。
- 2.內存的布局除了我們介紹的這四個分區外,還有其他的分區。僅僅是這四個分區與代碼的關系更加密切一些。
- 3.使用readelf工具能夠查看可執行文件裏的分區信息,只是這裏僅僅使用了該命令的S選項,其他的選項沒有介紹,大家能夠自己摸索一下。
- 4.通過/proc虛擬文件夾中的文件來查看內存相關的信息。主要有cmdline,maps,status。
readelf查看的是程序已經固定的靜態信息,像堆,棧這些動態信息,就須要查看proc文件夾中的文件了,該文件夾中的文件提供了程序執行時的實時信息。
各位看官。關於C程序內存布局的樣例咱們就講到這裏。欲知後面還有什麽樣例,且聽下回分解 。
一起talk C栗子吧(第一百三十一回:C語言實例--C程序內存布局三)