C/C++内存分配与Linux内存管理进程所涉及到的五个数据段 .
一. 在c中分為這幾個(gè)存儲(chǔ)區(qū)
1.棧 - 由編譯器自動(dòng)分配釋放
2.堆 - 一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)可能由OS回收
3.全局區(qū)(靜態(tài)區(qū)),全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。- 程序結(jié)束釋放
4.另外還有一個(gè)專(zhuān)門(mén)放常量的地方。- 程序結(jié)束釋放
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
在函數(shù)體中定義的變量通常是在棧上,用malloc, calloc, realloc等分配內(nèi)存的函數(shù)分配得到的就是在堆上。在所有函數(shù)體外定義的是全局量,加了static修飾符后不管在哪里都存放在全局區(qū)(靜態(tài)區(qū)),在所有函數(shù)體外定義的static變量表示在該文件中有效,不能extern到別的文件用,在函數(shù)體內(nèi)定義的static表示只在該函數(shù)體內(nèi)有效。另外,函數(shù)中的"adgfdf"這樣的字符串存放在常量區(qū)。比如:
int a = 0; //全局初始化區(qū)
char *p1; //全局未初始化區(qū)
void main()
{
??? int b; //棧
??? char s[] = "abc"; //棧
??? char *p2; //棧
??? char *p3 = "123456"; //123456{post.content}在常量區(qū),p3在棧上
??? static int c = 0; //全局(靜態(tài))初始化區(qū)
??? p1 = (char *)malloc(10); //分配得來(lái)得10字節(jié)的區(qū)域在堆區(qū)
??? p2 = (char *)malloc(20); //分配得來(lái)得20字節(jié)的區(qū)域在堆區(qū)
??? strcpy(p1, "123456");
??? //123456{post.content}放在常量區(qū),編譯器可能會(huì)將它與p3所指向的"123456"優(yōu)化成一塊
}
二.在C++中,內(nèi)存分成5個(gè)區(qū),他們分別是堆、棧、自由存儲(chǔ)區(qū)、全局/靜態(tài)存儲(chǔ)區(qū)和常量存儲(chǔ)區(qū)
1.棧,就是那些由編譯器在需要的時(shí)候分配,在不需要的時(shí)候自動(dòng)清楚的變量的存儲(chǔ)區(qū)。里面的變量通常是局部變量、函數(shù)參數(shù)等。
2.堆,就是那些由new分配的內(nèi)存塊,他們的釋放編譯器不去管,由我們的應(yīng)用程序去控制,一般一個(gè)new就要對(duì)應(yīng)一個(gè)delete。如果程序員沒(méi)有釋放掉,那么在程序結(jié)束后,操作系統(tǒng)會(huì)自動(dòng)回收。
3.自由存儲(chǔ)區(qū),就是那些由malloc等分配的內(nèi)存塊,他和堆是十分相似的,不過(guò)它是用free來(lái)結(jié)束自己的生命的。
4.全局/靜態(tài)存儲(chǔ)區(qū),全局變量和靜態(tài)變量被分配到同一塊內(nèi)存中,在以前的C語(yǔ)言中,全局變量又分為初始化的和未初始化的,在C++里面沒(méi)有這個(gè)區(qū)分了,他們共同占用同一塊內(nèi)存區(qū)。
5.常量存儲(chǔ)區(qū),這是一塊比較特殊的存儲(chǔ)區(qū),他們里面存放的是常量,不允許修改(當(dāng)然,你要通過(guò)非正當(dāng)手段也可以修改)
?
Linux內(nèi)存管理進(jìn)程所涉及到的五個(gè)數(shù)據(jù)段
進(jìn) 程(執(zhí)行的程序)會(huì)占用一定數(shù)量的內(nèi)存,它或是用來(lái)存放從磁盤(pán)載入的程序代碼,或是存放取自用戶(hù)輸入的數(shù)據(jù)等等。不過(guò)進(jìn)程對(duì)這些內(nèi)存的管理方式因內(nèi)存用途 不一而不盡相同,有些內(nèi)存是事先靜態(tài)分配和統(tǒng)一回收的,而有些卻是按需要?jiǎng)討B(tài)分配和回收的。對(duì)任何一個(gè)普通進(jìn)程來(lái)講,它都會(huì)涉及到5種不同的數(shù)據(jù)段。
一、Linux進(jìn)程的五個(gè)段
下面我們來(lái)簡(jiǎn)單歸納一下進(jìn)程對(duì)應(yīng)的內(nèi)存空間中所包含的5種不同的數(shù)據(jù)區(qū)都是干什么的。
1)代碼段:代碼段是用來(lái)存放可執(zhí)行文件的操作指令,也就是說(shuō)是它是可執(zhí)行程序在內(nèi)存中的鏡像。代碼段需要防止在運(yùn)行時(shí)被非法修改,所以只準(zhǔn)許讀取操作,而不允許寫(xiě)入(修改)操作——它是不可寫(xiě)的。
2)數(shù)據(jù)段:數(shù)據(jù)段用來(lái)存放可執(zhí)行文件中已初始化全局變量,換句話(huà)說(shuō)就是存放程序靜態(tài)分配的變量和全局變量。
3)BSS段:BSS段包含了程序中未初始化的全局變量,在內(nèi)存中 bss段全部置零。
4)堆(heap):堆是用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,它的大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張);當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除(堆被縮減)
? 它的物理內(nèi)存空間是由程序申請(qǐng)的,并由程序負(fù)責(zé)釋放。
5)棧:棧是用戶(hù)存放程序臨時(shí)創(chuàng)建的局部變量,也就是說(shuō)我們函數(shù)括弧“{}”中定義的變量(但不包括static聲明的變量,static意味著在數(shù)據(jù)段中存放變量)。除此以外,在函數(shù)被調(diào)用時(shí),其參數(shù)也會(huì)被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會(huì)被存放回棧中。由于棧的先進(jìn)先出特點(diǎn),所以棧特別方便用來(lái)保存/恢復(fù)調(diào)用現(xiàn)場(chǎng)。從這個(gè)意義上講,我們可以把堆棧看成一個(gè)寄存、交換臨時(shí)數(shù)據(jù)的內(nèi)存區(qū)。
?? 它是由操作系統(tǒng)分配的,內(nèi)存的申請(qǐng)與回收都由OS管理。
舉個(gè)具體的C語(yǔ)言的例子吧:
//main.c
int a = 0; //全局初始化區(qū)
char *p1; //全局未初始化區(qū)
main()
{
static int c =0; //全局(靜態(tài))初始化區(qū)
int b; //棧
char s[] = "abc"; //棧
char *p2; //棧
char *p3 = "123456"; //"123456/0"在常量區(qū),p3在棧上。
p1 = (char *)malloc(10);
p2 = (char *)malloc(20); //分配得來(lái)得10和20字節(jié)的區(qū)域就在堆區(qū)。
}
二、各個(gè)段在內(nèi)存中的組織
各個(gè)段段在線(xiàn)性空間中的組織。直接上圖:
+--------------------------------?? 高地址
+ envstrings 環(huán)境變量字串????
+--------------------------------
+ argv string 命令行字串????????
+--------------------------------
?
+ env pointers 環(huán)境變量指針表
+--------------------------------
+ argv pointers命令行參數(shù)指針表
+--------------------------------
+ argc 命令行參數(shù)個(gè)數(shù)?
+--------------------------------
?
+???? main函數(shù)的棧幀??
+--------------------------------
+???? 被調(diào)用函數(shù)的棧幀
+--------------------------------
+???????? ......????????????????
+--------------------------------
?
?
+?????? 堆(heap)????????????????
+--------------------------------
?
?
+?? BSS 未初始化全局?jǐn)?shù)據(jù)?????
+--------------------------------
?
?
+?? Data 初始化的全局?jǐn)?shù)據(jù)????
+--------------------------------
?
+?? Text? 代碼段????????????????
+--------------------------------???
?
其中,Heap,BSS,Data這三個(gè)段在物理內(nèi)存中是連續(xù)存放的,可以這么理解:這三個(gè)是一體的。Text、Stack是獨(dú)立存放的,這是現(xiàn)在Linux中個(gè)段的分布,在0.11中代碼段和數(shù)據(jù)段不是分立的,是在一起的也就是說(shuō)數(shù)據(jù)段和代碼段是一個(gè)段,當(dāng)然了,堆與BSS也與它們一起了。從0.11的task_struct中還可以看出數(shù)據(jù)段、堆棧段的描述符是一個(gè),都在ldt[2]處。
總結(jié)
以上是生活随笔為你收集整理的C/C++内存分配与Linux内存管理进程所涉及到的五个数据段 .的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 编写字符串比较函数strcmp .
- 下一篇: 如何安装MiniGUI 3.0在Linu