一,綜述 在C語言程序中, 代碼在內存中進行執(zhí)行的時候,我們粗略的將程序所占用的內存分為四個區(qū)域—-棧區(qū),堆區(qū),全局區(qū),代碼區(qū). 每個程序都有唯一的四個內存區(qū)域.我們需要熟悉和了解各個區(qū)域的特性,例如存儲什么類型的數(shù)據(jù), 有誰去申請開辟, 又有誰去管理釋放等等 二,內存四區(qū)介紹 <一>棧區(qū) 由編譯器自動分配釋放, 存放函數(shù)的參數(shù)值,局部變量等. 例如: 參數(shù)buf,參數(shù)bufsize和size都是存放在棧區(qū).當函數(shù)執(zhí)行完畢的時候,自動釋放 void recev(char* buf, int bufsize){ int size;} <二> 堆區(qū) 一般由程序員分配釋放(動態(tài)內存申請與釋放),若程序員不釋放,程序結束時可能由操作系統(tǒng)回收 例如:下面的src所指向的內存空間就是在堆區(qū) char* src = (char*) malloc(sizeof(buf) * sizeof(10)); <三>全局區(qū)(靜態(tài)區(qū)) 全局變量和靜態(tài)變量存放在此. 里面細分有一個常量區(qū), 字符串常量和其他常量也存放在此. 該區(qū)域是在程序結束后由操作系統(tǒng)釋放. <四> 程序代碼區(qū) 這個區(qū)域存放函數(shù)體的二進制代碼.也是由操作系統(tǒng)進行管理的 三, 劃分內存四區(qū)的意義 C語言程序中,根據(jù)是局部變量,全局變量, 常量還是通過malloc等類似的函數(shù)分配內存空間, 把他們放到對應的內存區(qū)中.這樣就賦予了這些變量或常量不同的生命周期, 不同的釋放方式. 根據(jù)我們程序的需要,我們在編碼過程中,聲明不同的變量類型, 使他們有不同的聲明長度, 不同的釋放方式,給我們更大的靈活編程 四,內存四區(qū)的一個示例 代碼如下: /*變量生命周期示例*/#include 'stdafx.h'#include #include/*訪問棧區(qū)*/int visitStackArea(){ printf('-----------------visitStackArea()---------------------\n'); int a = 10; printf('a的地址 %d\n',&a); return a;}/*訪問全局區(qū)*/char* visitGlobalArea(){ printf('----------------visitGlobalArea()----------------------\n'); char *str = 'abcdefg'; printf(' visitGlobalArea() str的地址是: %d\n',str); return str;}/*訪問堆區(qū)*/int* visitHeapArea(){ printf('-----------------visitHeapArea()---------------------\n'); int* chs = NULL; chs = (int*) malloc(sizeof(int)*10); for(int i=0; i<10; i++){ *(chs+i) = i; } printf(' visitHeapArea() chs的地址是: %d\n',chs); return chs;}int main(){ int a = visitStackArea(); printf('main通過visitStackArea()得到a的值, a的地址是: %d\n',&a); char* str = visitGlobalArea(); printf('main通過visitGlobalArea()得到str的值, str的地址是: %d\n',str); int* chs = visitHeapArea(); printf('main通過visitHeapArea()得到的chs的值, chs的地址是: %d\n',chs); free(chs); return 0;} - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
運行結果: -----------------visitStackArea()---------------------a的地址 3209584main通過visitStackArea()得到a的值, a的地址是: 3209836----------------visitGlobalArea()---------------------- visitGlobalArea() str的地址是: 20470000main通過visitGlobalArea()得到str的值, str的地址是: 20470000-----------------visitHeapArea()--------------------- visitHeapArea() chs的地址是: 7573184main通過visitHeapArea()得到的chs的值, chs的地址是: 7573184請按任意鍵繼續(xù). . . 結果分析: 1,visitStackArea()函數(shù)內的地址是:3209584,而main函數(shù)調用visitStackArea()得到的a的地址是:3209836. 雖然main函數(shù)調用了函數(shù)visitStackArea(),但是 a是兩塊內存中的 . 當main調用visitStackArea()結束后, 編譯器就把3209584地址釋放了, 在main函數(shù)中重新開辟地址3209836來存儲a 2,visitGlobalArea()函數(shù)內的str地址是:20470000, main函數(shù)調用visitGlobalArea()的地址也是20470000, 說明str的聲明周期存在于整個程序的運行期間. 我們由上面可知, 他是存儲在全局區(qū)的,當程序退出后由操作系統(tǒng)進行釋放管理 3,visitHeapArea()函數(shù)內的chs地址是:7573184,main函數(shù)調用visitHeapArea()得到的chs地址也是:7573184,也說明chs聲明周期比較長, 他聲明周期長到何種程度,這有程序員來決定, 調用free方法來釋放, 如果堆區(qū)的內存不手動free,那么將造成內存泄露(Memory Leak) PS:假設有兩個函數(shù)A,B, A調用B, 如果A主調函數(shù)想使用被調函數(shù)B中的變量分配的內存,可以嗎?
|