C語言 堆與棧
通過內存組織方式可以看到,堆用來存放動態(tài)分配內存空間,而棧用來存放局部數據對象、函數的參數以及調用函數和被調用函數的聯系,下面對二者進行詳細的說明。
1.堆
在內存的全局存儲空間中,用于程序動態(tài)分配和釋放的內存塊稱為自由存儲空間,通常也稱之為堆。
在C程序中,是用malloc()和free()函數從堆中動態(tài)地分配和釋放內存。
【例題】在堆中分配內存并釋放
程序如下:
#include<studio.h>
int main()
{
int *plnt; /*定義整型指針*/
pInt=(int*)malloc(sizeof(int)); /*分配內存*/
*plnt=100; /*使用分配內存*/
printf("the number is: %d\n", pint); /*輸出顯示數值*/
return 0; /*釋放內存*/
}
本程序中用malloc()函數分配一個整型變量的內存空間,在使用完該空間后,使用free()函數釋放。
2.棧
在函數調用時,第一個進棧的是主函數中函數調用后的下一條指令(函數調用語句的下一條可執(zhí)行語句)的地址,然后是函數的各個參數。在大多數的C編譯器中,參數是由右往左入棧的,然后是函數中的局部變量。注意靜態(tài)變量是不入棧的。
當本次函數調用結束后,局部變量先出棧,然后是參數,最后棧頂指針指向最開始存的地址,也就是主函數中的下一條指令,程序由該點繼續(xù)運行。
棧是一個后進先出的壓入彈出式的數據結構。在程序運行時,需要每次向棧中壓入一個對象,然后棧指針向下移動一個位置。當系統(tǒng)從棧中彈出一個對象時,最晚進棧的對象將被彈出,然后棧指針向上移動一個位置。如果棧指針位于棧頂,則表示棧是空的;如果棧指針指向最下面的數據項的后一個位置,則表示棧為滿的。其過程如圖所示。
程序員通常會利用棧這種數據結構來處理那些最適用后進先出邏輯描述的編程問題。這里討論的棧在程序中都會存在,它不需要程序員編寫代碼去維護,而是運行時由系統(tǒng)自動處理。所謂的運行時系統(tǒng)維護,實際上就是編譯器所產生的程序代碼。盡管在源代碼中看不到它們,但程序員應該對此有所了解。這個特性和后進先出的特性是棧明顯區(qū)別于堆的標志。
棧是如何工作的呢?例如,當一個函數A調用另一個函數B時,系統(tǒng)將會把函數A的所有實參和返回地址壓入到棧中,棧指針將移動到合適的位置來容納這些數據。最后進棧的是函數A的返回地址。
當函數B開始執(zhí)行后,系統(tǒng)把函數B的自變量壓入到棧中,并把棧指針再向下移,以保證有足夠的空間來存儲函數B聲明的所有自變量。
當函數A的實參壓入棧后,函數B就在棧中以自變量的形式建立了形參。函數B內部的其他自變量 也是存放在棧中的。由于這些進棧操作,棧指針已經壓到所有局部變量之下。但是函數B記錄了剛開始執(zhí)行時的初始棧指針,以這個指針為參考,用正偏移量或負偏移量來訪問棧中的變量。
當函數B正準備返回時,系統(tǒng)彈出棧中的所有自變量,這時棧指針移到了函數B剛開始執(zhí)行時的位置。接著,函數B返回,系統(tǒng)從棧中彈出返回地址,函數A就可以繼續(xù)執(zhí)行了。
當函數A繼續(xù)執(zhí)行時,系統(tǒng)還能從棧中彈出調用者的實參,于是棧指針又回到了調用前的位置。
點擊加載更多評論>>