malloc工作機制:
malloc函數的實質體現在,它有一個將可用的內存塊連接為一個長長的列表的所謂空閑鏈表(堆內存)。調用malloc函數時,它沿連接表尋找一個大到足以滿足用戶請求所需要的內存塊。然后,將該內存塊一分為二(一塊的大小與用戶請求的大小相等,另一塊的大小就是剩下的字節)。接下來,將分配給用戶的那塊內存傳給用戶,並將剩下的那塊(如果有的話)返回到連接表上。調用free函數時,它將用戶釋放的內存塊連接到空閑鏈上。到最后,空閑鏈會被切成很多的小內存片段,如果這時用戶申請一個大的內存片段,那么空閑鏈上可能沒有可以滿足用戶要求的片段了。於是,malloc函數請求延時,並開始在空閑鏈上翻箱倒櫃地檢查各內存片段,對它們進行整理,將相鄰的小空閑塊合並成較大的內存塊。如果無法獲得符合要求的內存塊,malloc函數會返回NULL指針,因此在調用malloc動態申請內存塊時,一定要進行返回值的判斷。
程序占用三種類型的內存:靜態內存、棧內存、堆內存;
靜態內存:用來保存局部static對象、類static數據成員以及定義在任何函數之外的變量
棧內存:用來保存定義在函數內的非static對象。分配在靜態內存或棧內存中的對象由編譯器自動創建和銷毀。對於棧對象,僅在其定義的程序塊運行時才存在;static對象在使用之前分配,在程序結束時銷毀。
堆內存:在程序運行時分配。動態對象的生存周期由程序(用戶)來控制。
關於使用free()函數釋放內存后實際數據是否存在的問題
關於用malloc分配的內存,在調用free釋放后,該內存的狀態,有以下幾點說明:
1.調用free釋放掉所分配的內存后,表明該內存可以被別人使用,也就是說,其他地方調用malloc后,可以分配到該內存
2.關於free釋放該內存后,該內存中的數據,我們只能認為是臟數據;也就是說,這部分數據可能存在並且維持原來的值,也可能被清空,或者被修改為其他值;
3.在釋放了該內存后,除了要對當時分配的指針賦值為NULL,還要注意不要再去引用這部分內存,不要嘗試獲取這部分的值,這些已經非法。
4.內存free后,里面的數據還是在的,只是這塊內存會被標記為可用的內存,別的程序可以用這塊內存里面的數據可能存在,只要該內存沒有被別的地方占用。你free釋放的是內存的使用權。
驗證代碼:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 struct stu1{ 5 char *name; //姓名 6 int num; //學號 7 int age; //年齡 8 char group; //所在小組 9 float score; //成績 10 }; 11 12 int main(){ 13 //給結構體成員賦值 14 struct stu1 *stu1; 15 { 16 stu1 = malloc(sizeof(struct stu1)); 17 stu1->name = "Tom"; 18 stu1->num = 12; 19 stu1->age = 18; 20 stu1->group = 'A'; 21 stu1->score = 136.5; 22 //讀取結構體成員的值 23 printf("%s的學號是%d,年齡是%d,在%c組,今年的成績是%.1f!\n", stu1->name, stu1->num, stu1->age, stu1->group, stu1->score); 24 printf("%p\n",stu1); 25 free(stu1); 26 } 27 scanf("%p",&stu1); 28 printf("%p\n",stu1); 29 printf("%s的學號是%d,年齡是%d,在%c組,今年的成績是%.1f!\n", stu1->name, stu1->num, stu1->age, stu1->group, stu1->score); 30 return 0; 31 }
