估計會有很多初學者跟我有一樣的疑惑,這些編寫好的代碼是放在磁盤中,但是運行將會被copy至內存中去運行。但他們在內存中是怎么分布呢。在?“linux下c編程圣經”(apue)UNIX環境高級編程一書中闡述了這一點。在這里結合網上資料以及這本書寫下自己的一點學習筆記。
在內存中程序分別存儲在如下幾個區域中:
一、正文區(Code?or?Text)
對于名字有很多,有的稱為代碼段,代碼區等等。但是實質都是一樣的,都是用來存放程序語句進行編譯后,形成機器的代碼。一般此內存區是只讀的,防止程序意外修改指令。
二、初始數據段(RO/RW?data?segment)
通常是用來存放程序中已初始化的全局變量的一塊內存區域。又分為只讀和讀寫兩種,此數據段屬于靜態內存分配
三、未初始化數據段(BSS?=?Block?Started?by?Symbol)
未初始化讀寫據是在程序中聲明,但是沒有初始化的變量,這些變量在程序運行之前不需要占用存儲器的空間.BSS段也屬于靜態內存分配
四、堆(heap)
堆內存只在程序運行時出現,一般由程序員手動分配和釋放,一般可以使用malloc()/nalloc()?&?free()?函數來申請、釋放。在操作系統下,如果程序員沒釋放,一般操作系統可以在程序結束后回收內存
五、棧(stack)
存放程序的局部變量(但不包括static聲明的變量,static意味著在數據段中存放變量)。除此以外,在函數被調用時,棧用來傳遞參數和返回值。由于棧的最大特點后進先出,所以棧特別方便用來保存/恢復調用現場。
用圖片來解釋會更加通俗。左圖是書上的。從圖上可以看到,棧(stack)是自頂向下生長的,即由高地址向低地址;堆(heap)是自底向上生長。右圖是棧的進出示意圖,很明顯的后進先出。
? ?
這里比較重要的概念主要是?棧 和 堆。在網上收集了下他們之間的 PK?“數據”
棧? ? | 堆 |
|
|
|
|
|
|
棧只有一個入口,就是棧指針,棧指針標識當前棧區域中已經使用與未使用的界限,程序訪問棧內存的時候都只能通過棧指針及其偏移量 |
|
|
? ??堆內存在分配的時候,可以在程序中判斷malloc()等函數的返回值是否為NULL來確定對內存是否分配成功,是否可以使用 |
棧內存由編譯器管理,不需要程序來管理,同時,函數內部的棧內存是不能被函數的調用者使用的 |
堆內存需要在程序中處理它的分配與釋放情況(由程序調用具體的庫函數管理),可以利用靈活的程序將堆內存的指針從函數的內部傳遞到函數的外部,這時各個函數都可以使用別的函數分配出來的堆內存。 |
棧的一些特殊定義:
棧限定只能在表的一端進行插入和刪除操作的線性表。允許插入和刪除的一端稱作“棧頂(top)”,不允許插入和刪除端稱作“棧底(bottom)”
空棧:這里有兩種說法。1.堆棧指針指向下一個將要放入數據的空位置時。
????????????????????? 2.棧頂指向棧底地址時,即棧內沒有數據時為空棧。
? (對于上面這兩種定義一直沒有找到權威的出處。網上兩種概念都存在,我也不知道哪種才是正確的,希望有明確此概念的大神提點下。)
滿棧:棧指針指向的是一個有可用數據的,也就是最后一個使用的空間。
有圖才有真相,沒圖沒人理.上圖咯。
上面把空棧的兩種定義都畫出來了,可能有一個是有誤的,等我找到權威定義后更新此文,把錯誤的說法列成反面例子,供大家“批斗”!