C語言編程程序的內存如何布局_第1頁
C語言編程程序的內存如何布局_第2頁
C語言編程程序的內存如何布局_第3頁
C語言編程程序的內存如何布局_第4頁
C語言編程程序的內存如何布局_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、1 C 語言編程程序的內存如何布局C 語言程序的運行方式一:C 語言程序的存儲區(qū)域由C 語言代碼(文本文件 形成可執(zhí)行程序(二進制文件 ,需要經(jīng)過編譯-匯編-連接三個階段。編譯過程把C 語言文本文件生成匯編程序,匯編過程把匯編程序形成二進制機器代碼,連接過程則將各個源文件生成的二進制機器代碼文件組合成一個文件。C 語言編寫的程序經(jīng)過編譯-連接后,將形成一個統(tǒng)一文件,它由幾個部分組成。在程序運行時又會產生其他幾個部分,各個部分代表了不同的存儲區(qū)域:1. 代碼段(Code或Text代碼段由程序中執(zhí)行的機器代碼組成。在C 語言中,程序語句進行編譯后,形成機器代碼。在執(zhí)行程序的過程中,CPU 的程序計

2、數(shù)器指向代碼段的每一條機器代碼,并由處理器依次運行。2. 只讀數(shù)據(jù)段(RO data只讀數(shù)據(jù)段是程序使用的一些不會被更改的數(shù)據(jù),使用這些數(shù)據(jù)的方式類似查表式的操作,由于這些變量不需要更改,因此只需要放置在只讀存儲器中即可。3. 已初始化讀寫數(shù)據(jù)段(RW data已初始化數(shù)據(jù)是在程序中聲明,并且具有初值的變量,這些變量需要占用存儲器的空間,在程序執(zhí)行時它們需要位于可讀寫的內存區(qū)域內,并具有初值,以供程序運行時讀寫。4. 未初始化數(shù)據(jù)段(BSS未初始化數(shù)據(jù)是在程序中聲明,但是沒有初始化的變量,這些變量在程序運行之前不需要占用存儲器的空間。5. 堆(heap堆內存只在程序運行時出現(xiàn),一般由程序員分配

3、和釋放。在具有操作系統(tǒng)的情況下,如果程序沒有釋放,操作系統(tǒng)可能在程序(例如一個進程 結束后回收內存。26. 棧(stack棧內存只在程序運行時出現(xiàn),在函數(shù)內部使用的變量、函數(shù)的參數(shù)以及返回值將使用棧空間,棧空間由編譯器自動分配和釋放。C 語言目標文件的內存布局看一個例子:int a = 0; /全局初始化區(qū),。data 段static int b=20; /全局初始化區(qū),。data 段char *p1; /全局未初始化區(qū) .bss段const int A = 10; /.rodata段void main(voidint b; /棧char s = "abc" /棧char

4、*p2; /棧static int c = 0; /全局(靜態(tài) 初始化區(qū) .data段char *p3 = "123456" /1234560在常量區(qū),p3 在棧上。p1 = (char* malloc(10;/分配得來的10和20個字節(jié)的區(qū)域就在堆區(qū)p2 = (char* malloc(20;3 strcpy(p1, "123456" /1234560 在常量區(qū),編譯器可能會將它與p3所指向的"123456" 優(yōu)化成一個地方代碼段、只讀數(shù)據(jù)段、讀寫數(shù)據(jù)段、未初始化數(shù)據(jù)段屬于靜態(tài)區(qū)域,而堆和棧屬于動態(tài)區(qū)域。代碼段、只讀數(shù)據(jù)段和讀寫數(shù)據(jù)

5、段將在鏈接之后產生,未初始化數(shù)據(jù)段將在程序初始化的時候開辟,而堆和棧將在程序的運行中分配和釋放。C 語言程序分為映像和運行時兩種狀態(tài)。在編譯-連接后形成的映像中,將只包含代碼段(Text、只讀數(shù)據(jù)段(RO Data和讀寫數(shù)據(jù)段(RW Data。在程序運行之前,將動態(tài)生成未初始化數(shù)據(jù)段(BSS,在程序的運行時還將動態(tài)形成堆(Heap區(qū)域和棧(Stack區(qū)域。一般來說,在靜態(tài)的映像文件中,各個部分稱之為節(jié)(Section,而在運行時的各個部分稱之為段(Segment。如果不詳細區(qū)分,可以統(tǒng)稱為段。知識點:C 語言在編譯和連接后,將生成代碼段(Text、只讀數(shù)據(jù)段(RO Data和讀寫數(shù)據(jù)段(RW

6、Data。在運行時,除了以上三個區(qū)域外,還包括未初始化數(shù)據(jù)段(BSS區(qū)域和堆(Heap區(qū)域和棧(Stack區(qū)域。二:C 語言程序的段1. 代碼段(code或text代碼段由各個函數(shù)產生,函數(shù)的每一個語句將最終經(jīng)過編繹和匯編生成二進制機器代碼(具體生生哪種體系結構的機器代碼由編譯器決定 。2. 只讀數(shù)據(jù)段(RO Data只讀數(shù)據(jù)段由程序中所使用的數(shù)據(jù)產生,該部分數(shù)據(jù)的特點是在運行中不需要改變,因此編譯器會將該數(shù)據(jù)段放入只讀的部分中。C 語言中的只讀全局變量,只讀局部變量,程序中使用的常量等會在編譯時被放入到只讀數(shù)據(jù)區(qū)。注意:定義全局變量const char a100="ABCDEFG&

7、quot;將生成大小為100個字節(jié)的只讀數(shù)據(jù)區(qū),并使用“ABCDEFG ”初始化。如果定義為:const char a ="ABCDEFG"則根據(jù)字符串長度生成8個字節(jié)的只讀數(shù)據(jù)段(還有0 ,所以在只讀數(shù)據(jù)段中,一般都需要做完全的初始化。3. 讀寫數(shù)據(jù)段(RW Data4 讀寫數(shù)據(jù)段表示了在目標文件中一部分可以讀也可以寫的數(shù)據(jù)區(qū),在某些場合它們又被稱為已初始化數(shù)據(jù)段,這部分數(shù)據(jù)段和代碼段,與只讀數(shù)據(jù)段一樣都屬于程序中的靜態(tài)區(qū)域,但具有可寫性的特點。通常已初始化的全局變量和局部靜態(tài)變量被放在了讀寫數(shù)據(jù)段,如: 在函數(shù)中定義static charb 100=“ABCDEFG ”

8、;讀寫數(shù)據(jù)區(qū)的特點是必須在程序經(jīng)過初始化,如果只定義,沒初始值,則不會生成讀寫數(shù)據(jù)區(qū),而會定位為未初始化數(shù)據(jù)區(qū)(BSS。如果全局變量(函數(shù)外部定義的變量 加入static 修飾,這表示只能在文件內使用,而不能被其他文件使用。4. 未初始化數(shù)據(jù)段(BSS與讀寫數(shù)據(jù)段類似,它也屬于靜態(tài)數(shù)據(jù)區(qū),但是該段中的數(shù)據(jù)沒有經(jīng)過初始化。因此它只會在目標文件中被標識,而不會真正稱為目標文件中的一段,該段將會在運行時產生。未初始化數(shù)據(jù)段只在運行的初始化階段才會產生,因此它的大小不會影響目標文件的大小。在C 語言的程序中,對變量的使用還有以下幾點需要注意:1. 函數(shù)體中定義的變量通常是在棧上,不需要在程序中進行管理

9、,由編繹器處理。2. 用malloc,calloc,realloc 等分配內存的函數(shù)所分配的內存空間在堆上,程序必須保證在使用free 釋放,否則會發(fā)生內存泄漏。3. 所有函數(shù)體外定義的是全局變量,加了static 后的變量不管是在函數(shù)內部或外部都放在全局區(qū)。4. 使用const 定義的變量將放于程序的只讀數(shù)據(jù)區(qū)。三:程序中段的使用下面用一個簡單的例子來說明C 語言中變量和段的對應關系。C 語言程序中的全局區(qū)(靜態(tài)區(qū) ,實際對應著下述幾個段:RO Data; RW Data ; BSS Data.一般來說,直接定義的全局變量在未初始化數(shù)據(jù)區(qū),如果該變量有初始化則是在已初始化數(shù)據(jù)區(qū)(RW Dat

10、a ,加上const 則將放在只讀數(shù)據(jù)區(qū)。const char ro = "this is read only data" /只讀數(shù)據(jù)區(qū)static char rw_1 ="this is global read write data" /已初始化讀寫數(shù)據(jù)段5 char BSS_1 100; /未初始化數(shù)據(jù)段const char *ptrconst ="constant data" /字符串放在只讀取數(shù)據(jù)段int main(short b; /在棧上,占用2個字節(jié)char a100; /在棧上開辟100個字節(jié), 它的值是其首地址cha

11、r s ="abcdefg" /s在棧上,占用4個字節(jié),"abcdefg" 本身放置在只讀數(shù)據(jù)存儲區(qū),占8個字節(jié)char *p1; /p1在棧上,占用4個字節(jié)char *p2="123456" /p2 在棧上,p2指向的內容不能改,“123456”在只讀數(shù)據(jù)區(qū)static char rw_2 ="this is local read write data"/局部已初始化讀寫數(shù)據(jù)段static char BSS_2100; /局部未初始化數(shù)據(jù)段static int c = 0; /全局(靜態(tài) 初始化區(qū)p1=(char

12、 *malloc(10 * sizeof(char ; /分配內存區(qū)域在堆區(qū)strcpy(p1,"xxxx" /“XXXX ”放在只讀數(shù)據(jù)區(qū),占5個字節(jié)free(p1; /使用free 釋放p1所指向的內存return 0;讀寫數(shù)據(jù)段包含了憶初始化的全局變量 static char rw_1 以及局部靜態(tài)變量static rw_2 .其差別在 于編繹時,是在函數(shù)內部使用的還是可以在整個文件中使用。對于 rw_1 無論有無 static 修飾,其都將被 放置在讀寫數(shù)據(jù)區(qū),只是能否被其它文件引用與否。對于后者就不一樣了,它是局部靜態(tài)變量,放置在讀 寫數(shù)據(jù)區(qū),如果沒 static 修飾,其意義完全改變,它將會是開辟在??臻g的局部變量,而不是靜態(tài)變量, 在這里 rw_1,rw_2后沒具體數(shù)值,表示靜態(tài)區(qū)大小同后面字符串長度決定。 對于未初始化數(shù)據(jù)區(qū) BSS_1100與 BSS_2100,其區(qū)別在于前者是全局變量,在所有文件中都可以 使用;后者是局部變量,只在函數(shù)內部使用。未初始化數(shù)據(jù)段不設置后面的初始化數(shù)值,因此必須使用數(shù)值 指定區(qū)域的大小,編繹器將根據(jù)大小設置 BSS 中需要增加的長度。 ??臻g主要用于以下3數(shù)據(jù)的存儲: 1.函數(shù)內部的動態(tài)變量 2.函數(shù)的參數(shù) 3.函數(shù)的返回值 棧空間是動態(tài)開辟與回收的。在函數(shù)調用

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論