這一節主要講解了C語言里變數在記憶體中的位置,各種變數的使用區別,以及如何在堆棧中分配空間等C語言記憶體管理問題。 自動變數與靜態變數 auto自動變數 auto是預設的關鍵字,如實際中int a,實際為auto int a,{}內部的都是auto變數,不用為此類變數申請或者釋放空間,它都是自動完成的。 ...
這一節主要講解了C語言里變數在記憶體中的位置,各種變數的使用區別,以及如何在堆棧中分配空間等C語言記憶體管理問題。
自動變數與靜態變數
auto自動變數
auto是預設的關鍵字,如實際中int a,實際為auto int a,{}內部的都是auto變數,不用為此類變數申請或者釋放空間,它都是自動完成的。
register 變數
例:register int a = 0;
要使用register變數必須使用此關鍵字。
static 靜態變數
記憶體位置在程式執行期間一直不改變,一個代碼的內部靜態變數只能被這個代碼塊內部訪問,函數里使用載入到記憶體時只會初始化一次,每次訪問該函數時不會再初始化。
例:static int b = 0;
全局變數與靜態變數
全局變數的存儲方式與靜態變數相同,可以被多個文件訪問,在{}之外的變數。
例:
1 //main.c 2 3 int a = 0; 4 5 Void main{} 6 7 // main1.c 8 9 extern int a; 10 11 Test(){ 12 a…….}
靜態全局變數:只能在定義它的文件內部訪問,在其它文件外部是不可以被訪問的。
對於函數在存在靜態函數,表示該函數也只能在文件內部訪問,不可以在文件外部訪問。如果一個代碼塊之外的函數或者變數,C語言都預設是全局的,可以在其它文件被訪問,除非有關鍵字static,靜態函數始終在代碼區,static只表示它對外部是否可見。
例:static void test()
記憶體佈局
代碼區
程式被操作系統載入到記憶體的時候,所有的可執行代碼都被載入到代碼區,也叫代碼段,這塊記憶體在運行期間是不可以被修改的,只可以被執行。
靜態區
所有的靜態變數和全局變數都被放到了靜態區,程式退出的時候消失,在運行期間都占用記憶體。
棧區
所有的自動變數,函數的形參、返回值都是自動放入棧中,當一個變數超出其作用域時,自動從棧中彈出,不同系統的棧大小是不同的,windows操作系統是棧大小是可以設置的。C語言的形參是從左到右入棧的。
堆區
堆是一個大容器,它的容量遠遠大於棧,操作也更加複雜。堆中分配的記憶體不會自動釋放,需要用free手動釋放。一個程式的棧大小是有限的, 一個數組太大有可能導致棧溢出,不要在棧裡面定義太大的數組。如果使用一個特別大的數組,那麼使用堆而不是棧;如果一個數組在定義時不確定大小,那麼適合使用堆,不適用棧。Malloc如果分配記憶體不釋放,就會造成記憶體泄漏。Windows操作系統堆每次分配的空間是4k,4K為一頁,優點不用頻繁調度資源,缺點是可能浪費了記憶體。
void *malloc(int size_t);
例:char* =malloc(10);
Malloc分配空間的初始值是不固定的。
函數返回一個指針
1 //例1: 2 int *test(){ 3 Int *p = malloc(1*sizeof(int));//函數不能直接返回一個auto類型的地址 4 *p = 10; 5 Return p; 6 } 7 // 例2: 8 const char *test(){ 9 Const char *s = “hello”; 10 Return s;//意思是將s指向一個常量地址,常量在程式運行期間一直都是有效的。常量區和靜態區是有效的,程式運行期間一直有效,但是常量區是只讀的空間。 11 } 12 13 //例3: 14 const char *test(){ 15 Return“hello world”; 16 }
堆空間實現動態大小變化的字元數組
1 //例: 2 char a[] = “asfsb”; 3 4 char b[] = “jhansdnfsdg” 5 6 char *p = malloc(strlen(a)+strlen(b)+1); 7 8 strcpy(p,a); 9 10 strcat(p,b);
calloc與realloc的使用
Void *calloc(size_t nmemb, size_t size)
Malloc的參數是指定分配的大小,單位是位元組。
Calloc第一個參數是指定單位的數量,第二個參數指定一個單位的大小。
例:用malloc分配10個int
Int *p = malloc(10*sizeof(int));
用calloc分配10個int
Int *p = malloc(10,sizeof(int));
以上兩種寫法分配堆空間的大小是一樣的,malloc只負責分配空間大小,用memset負責清空;Calloc負責分配空間大小,同時負責將空間分配。
Void *realloc(void *ptr, size_t size)
Realloc在已分配的空間基礎上,重新擴大或縮小這塊空間。用realloc分配的空間也不會將新改變的空間清空。
通過指針形參分配記憶體的說明
//例: void test(char *s){ s =calloc(10,1); strcpy(s,”hello”); }//錯誤 void test(char **s){ *s =calloc(10,1); strcpy(*s,”hello”); }//正確
當你想內部給形參分配空間時,形參一定是個二級指針。
以上便是C語言記憶體管理的基本內容。