什麼變數存放在棧和堆
阿新 • • 發佈:2018-12-24
內容會持續更新,有錯誤的地方歡迎指正,謝謝!
什麼是棧區,什麼是堆區
棧區(stack):由編譯器自動分配釋放 ,存放函式的引數值、區域性變數的值等,記憶體的分配是連續的,類似於陣列,當我們宣告變數時,編譯器會自動接著當前棧區的結尾來分配記憶體。
堆區(heap):由程式設計師分配釋放, 若程式設計師不釋放,程式結束時由OS回收,記憶體的分配不是連續的,類似於連結串列。
變數存放的位置
C/C++程式佔用的記憶體分為以下幾部分:
- 程式程式碼區
- 常量區存放常量。程式結束時由OS回收。
- 全域性區(靜態區)存放全域性變數和靜態變數。初始化的全域性變數和靜態變數在一塊區域,未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。 程式結束時由OS回收。
- 堆區存放的變數(用new,malloc,calloc,realloc等分配記憶體函式得到的變數)由程式設計師分配釋放。
- 棧區存放的變數(區域性變數、函式引數等)由編譯器自動分配釋放。
記憶體模型:
舉例
int a = 0; //全域性初始化區
char *p1; //全域性未初始化區
void main()
{
int b; //棧
char s[] = “abc“;//棧
char *p2; //棧
char *p3 = “123456“; //123456\0在常量區,p3在棧上;體會與 char s[]="abc"; 的不同
static int c =0; //全域性初始化區
p2 = (char *)malloc(20); //堆區
strcpy(p1, “123456“); //123456\0在常量區,編譯器可能將它與p3指向的 “123456 “優化成一塊
}
棧區和堆區的關係
1.當一個函式呼叫完返回後它會釋放該函式中所有的棧空間。棧是由編譯器自動管理的,不用你操心。堆是動態分配記憶體的,並且你可以分配使用很大的記憶體,但是用不好會產生記憶體洩漏(比如在for迴圈中忘記釋放申請的記憶體)。
2.棧是機器系統提供的資料結構,特點是快速高效,缺點是有限制,資料不靈活,不會產生記憶體碎片。
3.堆是C/C++函式庫提供的,特點是靈活方便,資料適應面廣泛,但是效率有一定降低,頻繁申請和釋放記憶體會產生記憶體碎片。
總結
使用棧如同在食堂吃飯,只用點菜付錢(申請)、吃(使用),吃飽了就走,不必理會切菜、洗菜等準備工作和洗碗、刷鍋等掃尾工作。快捷,但自由度小。
使用堆如同在家吃飯,自己動手做喜歡吃的菜。比較麻煩,但比較符合自己的口味,而且自由度大。