現(xiàn)代操作系統(tǒng)對每個進(jìn)程都分配了完整的虛擬內(nèi)存地址空間。進(jìn)程會把整個地址空間分成多個區(qū)間來使用。 程序員最為熟悉的兩個區(qū)間莫過于堆和棧。然而還有其他的內(nèi)存區(qū)間來存儲代碼、靜態(tài)、全局變量等等。 本文來總結(jié)一下這些內(nèi)存區(qū)間到底存的是哪些東西。先看圖:
虛擬內(nèi)存技術(shù)使得每個進(jìn)程都可以獨(dú)占整個內(nèi)存空間,地址從零開始,直到內(nèi)存上限。 每個進(jìn)程都將這部分空間(從低地址到高地址)分為六個部分:
malloc
或new
申請的內(nèi)存。其中堆和棧的大小是可變的,堆從下往上生長,棧從上往下生長。
由于常量存儲在TEXT段中,所有對常量的賦值都將產(chǎn)生segment fault
異常。
可以認(rèn)為BSS段中的所有字節(jié)都是0。因?yàn)槲闯跏蓟娜肿兞?、靜態(tài)變量都在BSS段中, 所以它們都會被初始化為0,同時類的成員變量也會被初始化為0,但編譯器不保證局部變量的初始化。
上面說棧(STACK)是從上到下(高地址到低地址)分配的,而且我們知道, 函數(shù)的局部變量的空間是在進(jìn)入函數(shù)體后才分配的,在??臻g里。來個例子來看看吧!
int main(){ char a=0, b=0; int *p = (int*)&b; *p = 258; printf("%d %d", a, b); return 0;}
輸出是
1 2
正常來講先分配a
的地址,再分配b
的地址,大小均為1字節(jié),同時它們的地址是連續(xù)的! 然后對b
的地址進(jìn)行賦值258(二進(jìn)制表示是1 0000 0002
)。 后面8位0000 0002
賦值給了b
,前面的1
賦值給了a
。
上述結(jié)果和CPU端模式也有關(guān)系!我的CPU是小端字節(jié)序的~ 低位存的是低字節(jié)。
除非注明,本博客文章均為原創(chuàng),轉(zhuǎn)載請以鏈接形式標(biāo)明本文地址: http://harttle.com/2015/07/22/memory-segment.html