您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“C語言棧、堆和靜態存儲區怎么使用”,內容詳細,步驟清晰,細節處理妥當,希望這篇“C語言棧、堆和靜態存儲區怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
棧是現代計算機程序里最為重要的概念之一
棧在程序中用于維護函數調用上下文
函數中的參數和局部變量存儲在棧上
棧保存了一個函數調用所需的維護信息
參數
返回地址
局部變量
調用上下文
每次函數調用都對應著一個棧上的活動記錄
調用函數的活動記錄位于棧的中部
被調函數的活動記錄位于棧的頂部
從main() 開始運行
main() 調用 f()
當從 f() 調用中返回 main()
函數調用時,對應的棧空間在函數返回前是專用的
函數調用結束后,棧空間將被釋放,數據不再有效
下面看一個指向棧數據的指針:
#include <stdio.h> int* g() { int a[10] = {0}; return a; } void f() { int i = 0; int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int *pointer = g(); for (i = 0; i < 10; i++) { b[i] = pointer[i]; } for(i = 0; i < 10; i++) { printf("%d\n", b[i]); } } int main() { f(); return 0; }
輸出結果如下:
如果把
for (i = 0; i < 10; i++)
{
b[i] = pointer[i];
}
注釋了,直接打印 pointer[i] 里面的數據,如下:
#include <stdio.h> int* g() { int a[10] = {0}; return a; } void f() { int i = 0; int b[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int *pointer = g(); /* for (i = 0; i < 10; i++) { b[i] = pointer[i]; } */ for(i = 0; i < 10; i++) { printf("%d\n", pointer[i]); } } int main() { f(); return 0; }
輸出結果如下:
為什么直接打印 pointer[i] 里面的值會是這樣呢?因為 pointer 指向的空間是棧空間,棧空間在 g() 函數返回之后,活動記錄就被釋放了。被釋放后調用 printf 函數,printf 函數需要在棧上面建立一個活動記錄。這個活動記錄就會有 printf 函數的參數信息和返回值等,所以 pointer 所指向的內存里面的數據由于 printf 函數的調用被改變了。因此,不能返回局部變量的地址,不能返回局部數組的數組名。
堆是程序中一塊預留的內存空間,可由程序自由使用
堆中被程序申請使用的內存在被主動釋放前將一直有效
為什么有了棧還需要堆?
答:棧上的數據在函數返回后就會被釋放掉,無法傳遞到函數外部,如:局部數組
C語言程序中通過庫函數的調用獲得堆空間
頭文件:malloc.h
malloc -- 以字節的方式動態申請堆空間
free -- 將堆空間歸還給系統
系統對堆空間的管理方式
空閑鏈表法,位圖法,對象池法等等
以 int* p = (int*)malloc(sizeof(int)); 為例,要申請 4 個字節的大小,遍歷之后發現跟 5 Bytes 這個節點最接近,找到一個可以用的單元之后,就將這個單元的地址返還給了 p 指針。以前也提過使用 malloc 申請內存空間時返回的內存空間可能比申請的實際內存空間要大一點點,原因就是在空閑鏈表管理堆空間這樣的系統里面,它會找最近的那個,找到后的一般都大于等于所需要的內存空間,假如 5 Bytes 這個節點下所有的空閑內存單元都用完的話,就會找 12 Bytes 節點下的內存單元,這樣malloc 返回的內存空間就有可能比自己實際申請的內存空間要大。
靜態存儲區隨著程序的運行而分配空間
靜態存儲區的生命周期直到程序運行結束
在程序的編譯期靜態存儲區的大小就已經確定
靜態存儲區主要用于保存全局變量和靜態局部變量
靜態存儲區的信息最終會保存到可執行程序中
下面看一個靜態存儲區的驗證代碼:
#include <stdio.h> int g_v = 1; static int g_vs = 2; void f() { static int g_vl = 3; printf("%p\n", &g_vl); } int main() { printf("%p\n", &g_v); printf("%p\n", &g_vs); f(); return 0; }
輸出結果如下:
可以看到這三個地址是順序存放的,因為這三個變量都是存放在程序的靜態存儲區,靜態存儲區在程序里面有固定的起始地址。
讀到這里,這篇“C語言棧、堆和靜態存儲區怎么使用”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。