一個程序的內(nèi)存空間:
代碼段: 只讀,可共享; 代碼段(code segment/text segment )通常是指用來存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域。這部分區(qū)域的大小在程序運(yùn)行前就已經(jīng)確定动看,并且內(nèi)存區(qū)域通常屬于只讀, 某些架構(gòu)也允許代碼段為可寫,即允許修改程序卸奉。在代碼段中睬塌,也有可能包含一些只讀的常數(shù)變量,例如字符串常量等昆庇。
數(shù)據(jù)段: 儲存已被初始化了的靜態(tài)數(shù)據(jù)末贾。數(shù)據(jù)段(data segment )通常是指用來存放程序中已初始化的全局變量的一塊內(nèi)存區(qū)域。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配整吆。
BSS 段:未初始化的數(shù)據(jù)段. BSS 段(bss segment )通常是指用來存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域拱撵。BSS 是英文Block Started by Symbol 的簡稱辉川。BSS 段屬于靜態(tài)內(nèi)存分配。
[ 注意:BSS段 和 data段的區(qū)別是 拴测,如果一個全局變量沒有被初始化(或被初始化為0)乓旗,那么他就存放在bss段;如果一個全局變量被初始化為非0集索,那么他就被存放在data段屿愚。]
堆(heap ): 堆是用于存放進(jìn)程運(yùn)行中被動態(tài)分配的內(nèi)存段,它的大小并不固定务荆,可動態(tài)擴(kuò)張或縮減妆距。當(dāng)進(jìn)程調(diào)用malloc 等函數(shù)分配內(nèi)存時,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴(kuò)張)函匕;當(dāng)利用free 等函數(shù)釋放內(nèi)存時娱据,被釋放的內(nèi)存從堆中被剔除(堆被縮減)
棧(stack) :棧又稱堆棧,是用戶存放程序臨時創(chuàng)建的局部變量浦箱,也就是說我們函數(shù)括弧“{} ”中定義的變量(但不包括static 聲明的變量吸耿,static 意味著在數(shù)據(jù)段中存放變量)。除此以外酷窥,在函數(shù)被調(diào)用時咽安,其參數(shù)也會被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后蓬推,函數(shù)的返回值也會被存放回棧中妆棒。由于棧的先進(jìn)先出特點,所以棧特別方便用來保存/ 恢復(fù)調(diào)用現(xiàn)場沸伏。從這個意義上講糕珊,我們可以把堆棧看成一個寄存毅糟、交換臨時數(shù)據(jù)的內(nèi)存區(qū)红选。
分布如下圖所示:
注意:
圖中間在棧和堆之間,有一個共享內(nèi)存的映射的區(qū)域姆另。這個就是共享內(nèi)存存放的地方喇肋。一般共享內(nèi)存的默認(rèn)大小是32M。
一個查看程序 data段迹辐,bss段蝶防,代碼段的命令 : size命令
對于如下的兩個程序 :
區(qū)別在于 arr[10] 一個有初始化,一個沒有初始化明吩。使用size命令查看一下:
小結(jié) :
1、經(jīng)過初始化的全局變量和靜態(tài)變量保存在數(shù)據(jù)段中低葫。
2详羡、未經(jīng)初始化的全局變量和靜態(tài)變量保存在BSS段。
3氮采、函數(shù)內(nèi)部聲明的局部變量保存在堆棧段中殷绍。
4、const修飾的全局變量保存在文本段中鹊漠,const修飾的局部變量保存在堆棧段中。
5茶行、字符串常量保存在文本段中躯概。
read more:
http://blog.sina.com.cn/s/blog_53fab15a01019lbq.html
另外一個問題
上面說到了一個進(jìn)程的進(jìn)程空間分布,下面的寫一個進(jìn)程下多個線程的空間分布畔师。
一個進(jìn)程下的多個線程的資源是共享的娶靡,只有 棧,棧指針和寄存器 是獨立的看锉。這樣可以保證多個線程去訪問函數(shù)的時候姿锭,不會出現(xiàn)數(shù)據(jù)不一致的問題。
每個線程獨立的棧有多大伯铣?
默認(rèn)的線程棧是8m呻此。如何修改默認(rèn)的線程棧的大小腔寡?
typedef struct __pthread_attr_s
{
int __detachstate; //分離狀態(tài)
int __schedpolicy;//調(diào)度策略
struct __sched_param __schedparam;
int __inheritsched;
int __scope;//線程優(yōu)先級的有效范圍
size_t __guardsize;//
int __stackaddr_set;
void *__stackaddr;//起始地址
size_t __stacksize;//表示堆棧的大小
}pthread_attr_t;
// pthread_attr_t 線程的屬性
// 也就是我們創(chuàng)建線程的第二個參數(shù)
if(pthread_create(&p1,NULL,th1,NULL)!=0){
cout<<"thread create error"<<endl;
}
可以配合pthread_attr_setstack使用設(shè)置線程棧,由此看來線程棧在所進(jìn)程的堆區(qū)焚鲜,所以線程與其所屬的進(jìn)程共享進(jìn)程的虛擬地址空間.