C语言程序的存储区域
由C語言代碼(文本文件)形成可執(zhí)行程序(二進制文件),需要經(jīng)過編譯-匯編-連接三個階段。編譯過程把C語言文本文件生成匯編程序,匯編過程把匯編程序形成二進制機器代碼,連接過程則將各個源文件生成的二進制機器代碼文件組合成一個文件。
C語言編寫的程序經(jīng)過編譯-連接后,將形成一個統(tǒng)一文件,它由幾個部分組成。在程序運行時又會產(chǎn)生其他幾個部分,各個部分代表了不同的存儲區(qū)域:
1.代碼段(Code或Text)
代碼段由程序中執(zhí)行的機器代碼組成。在C語言中,程序語句進行編譯后,形成機器代碼。在執(zhí)行程序的過程中,CPU的程序計數(shù)器指向代碼段的每一條機器代碼,并由處理器依次運行。
2.只讀數(shù)據(jù)段(RO data)
只讀數(shù)據(jù)段是程序使用的一些不會被更改的數(shù)據(jù),使用這些數(shù)據(jù)的方式類似查表式的操作,由于這些變量不需要更改,因此只需要放置在只讀存儲器中即可。
3.已初始化讀寫數(shù)據(jù)段(RW data)
已初始化數(shù)據(jù)是在程序中聲明,并且具有初值的變量,這些變量需要占用存儲器的空間,在程序執(zhí)行時它們需要位于可讀寫的內(nèi)存區(qū)域內(nèi),并具有初值,以供程序運行時讀寫。
4.未初始化數(shù)據(jù)段(BSS)
未初始化數(shù)據(jù)是在程序中聲明,但是沒有初始化的變量,這些變量在程序運行之前不需要占用存儲器的空間。
5.堆(heap)
堆內(nèi)存只在程序運行時出現(xiàn),一般由程序員分配和釋放。在具有操作系統(tǒng)的情況下,如果程序沒有釋放,操作系統(tǒng)可能在程序(例如一個進程)結(jié)束后回收內(nèi)存。
6.棧(stack)
棧內(nèi)存只在程序運行時出現(xiàn),在函數(shù)內(nèi)部使用的變量、函數(shù)的參數(shù)以及返回值將使用棧空間,棧空間由編譯器自動分配和釋放。
看一個例子:
?| int a = 0; //全局初始化區(qū)。??????? data段 ?static int b=20; //全局初始化區(qū)。? data段 ?char *p1; //全局未初始化區(qū)???????? bss段 ?const int A = 10; //???????????? rodata段 ?void main(void) ?{ ?int b; //棧 ?char s[] = "abc"; //棧 ?char *p2; //棧 ?static int c = 0; //全局(靜態(tài))初始化區(qū) .data段 ?char *p3 = "123456"; //123456\0在常量區(qū),p3 在棧上。 ?p1 = (char*) malloc(10);//分配得來的10和20個字節(jié)的區(qū)域就在堆區(qū) ?p2 = (char*) malloc(20); ?strcpy(p1, "123456"); //123456\0 在常量區(qū),編譯器可能會將它與p3所指向的"123456"優(yōu)化成一個地方 ?} |
代碼段、只讀數(shù)據(jù)段、讀寫數(shù)據(jù)段、未初始化數(shù)據(jù)段屬于靜態(tài)區(qū)域,而堆和棧屬于動態(tài)區(qū)域。代碼段、只讀數(shù)據(jù)段和讀寫數(shù)據(jù)段將在鏈接之后產(chǎn)生,未初始化數(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)。如果不詳細(xì)區(qū)分,可以統(tǒng)稱為段。
在C語言的程序中,對變量的使用還有以下幾點需要注意:
??? 1.函數(shù)體中定義的變量通常是在棧上,不需要在程序中進行管理,由編繹器處理。
??? 2.用malloc,calloc,realloc等分配內(nèi)存的函數(shù)所分配的內(nèi)存空間在堆上,程序必須保證在使用free釋放,否則會發(fā)生內(nèi)存泄漏。
??? 3.所有函數(shù)體外定義的是全局變量,加了static后的變量不管是在函數(shù)內(nèi)部或外部都放在全局區(qū)。
??? 4.使用const定義的變量將放于程序的只讀數(shù)據(jù)區(qū)。
棧空間主要用于以下3數(shù)據(jù)的存儲:
??? 1.函數(shù)內(nèi)部的動態(tài)變量
??? 2.函數(shù)的參數(shù)
??? 3.函數(shù)的返回值
棧空間是動態(tài)開辟與回收的。在函數(shù)調(diào)用過程中,如果函數(shù)調(diào)用的層次比較多,所需要的棧空間也逐漸加大,對于參數(shù)的傳遞和返回值,如果使用較大的結(jié)構(gòu)體,在使用的棧空間也會比較大。
?轉(zhuǎn)自:http://www.cnblogs.com/lyp3314/archive/2012/05/13/2497954.html
轉(zhuǎn)載于:https://www.cnblogs.com/rollenholt/articles/2529227.html
總結(jié)
以上是生活随笔為你收集整理的C语言程序的存储区域的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 虚位以待C#-北京Objectiva
- 下一篇: 页面的生命周期