有關於malloc申請內存和free內存釋放


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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM