c語言中的動態記憶體分配函式malloc和free使用起來很靈活,但是也很容易導致錯誤,
如果知道了malloc和free的實現原理,那麼,出錯的機會就很小了。
malloc的實現原理:
作業系統維護了乙個將可用的記憶體塊連線為乙個長長的列表的所謂空閒鍊錶。
呼叫malloc函式時,作業系統沿鍊錶尋找乙個大到足以滿足使用者請求所需要的記憶體塊。然後,將該記憶體塊一分為二(一塊的大小與使用者請求的大小相等,另一塊的大小就是剩下的位元組)。接下來,將分配給使用者的那塊記憶體傳給使用者,並將剩下的那塊(如果有的話)返回到鍊錶上。呼叫free函式時,它將使用者釋放的記憶體塊連線到空閒鍊錶上。
free的實現原理:
作業系統在呼叫malloc函式時,會預設在malloc分配的物理記憶體前面分配乙個資料結構,這個資料結構記錄了這次分配記憶體的大小,在使用者眼中這個操作是透明的。
那麼當使用者需要free時,free函式會把指標退回到這個結構體中,找到該記憶體的大小,這樣就可以正確的釋放記憶體了。
通過這種記憶體分配機制,可以解釋很多c語言中的迷惑問題:
1)使用者已經free了一段記憶體,為什麼還可以呼叫該指標,並且編譯器不報錯?
因為,free函式的作用只是告訴作業系統該記憶體不用了,可以收回,作業系統就把該記憶體鏈結到鏈結表上,
但是這段記憶體使用者還是可以訪問到的,只是該記憶體的值可能已經發生了變化,這種情況也叫作野指標。
解決辦法就是,在free後,把該指標指向null。
12 void test(void)
13 25 }
上面程式會列印出什麼?
會列印出:
str1=
str=world
free 只是釋放的str指向的記憶體空間,它本身的值還是存在的.
所以free之後,有乙個好的習慣就是將str=null.
此時str指向空間的記憶體已被**,如果輸出語句之前還存在分配空間的操作的話,這段儲存空間是可能被重新分配給其他變數的,
儘管這段程式確實是存在大大的問題(上面各位已經說得很清楚了),但是通常會列印出world來。
這是因為,程序中的記憶體管理一般不是由作業系統完成的,而是由庫函式自己完成的。
當你malloc一塊記憶體的時候,管理庫向作業系統申請一塊空間(可能會比你申請的大一些),然後在這塊空間中記錄一些管理資訊(一般是在你申請的記憶體前面一點),並將可用記憶體的位址返回。但是釋放記憶體的時候,管理庫通常都不會將記憶體還給作業系統,因此你是可以繼續訪問這塊位址的,只不過。。。。。。。。最好別這麼幹。
2)使用者在malloc時,分配了100位元組,int *指標指向該記憶體,那麼free時,是釋放100位元組還是釋放4位元組?
因為作業系統在malloc分配記憶體時,會在該記憶體的實體地址的前面維護乙個資料結構,該資料結構記錄了這次分配記憶體的大小,所以當使用者free時,free函式會把該int *指標退回到該資料結構中,找到該記憶體的大小,這樣free函式就可以正確的釋放
該段記憶體了。
答案:釋放100位元組,而不是4位元組。
3)使用者malloc了100位元組的記憶體,int *指標指向該記憶體,同時定義了char *的指標,也指向該記憶體,那麼free(char *),是釋放
1個位元組還是釋放100個位元組?
原理同上面的問題一樣,只是這個問題的更具隱蔽性,也容易誤解。
因為free函式的原理是退回到該物理記憶體的前面,找到記錄該記憶體大小的資料結構,所以,即使是char *指標,free也可以正確的釋放該記憶體。
答案:釋放100位元組,而不是1個位元組
free需要釋放malloc定義的首位址。
eg:int *a;
a = (int *)malloc(100);
*a++ = 0;
*a++ = 1;
再用free釋放的的時候一定把a的位址指向malloc分配時候的首位址
a--;
a--;
這樣採用用free(a);
當然也可以定義乙個int *b;在最開始的時候 b = a;
這樣就可以free(b)了。
free函式和malloc函式
初學c和資料結構是對其很不明確,通過一些資料,稍微理解了,所以記下以後複習之用,如果有錯誤或者理解不當的情況請指正,不勝感激。一malloc和free函式 malloc函式 void malloc sizeof byte 向系統申請大小的空間,然後返回指向這個記憶體的指標。如果記憶體分配失敗,則返回...
malloc與free函式用法
在c裡,記憶體管理是通過專門的函式來實現。另外,為了相容各種程式語言,作業系統提供的介面通常是c 語言寫成的函式宣告 windows 本身也由c和組合語言寫成 1分配記憶體malloc函式 需要包含標頭檔案 include 函式宣告 函式原型 void malloc int size 說明 mall...
自引用結構兼談Malloc和Free函式
一 自引用結構 1 什麼事自引用結構?自引用結構 self referential structure 是一種特殊的結構。主要特徵 乙個或多個自身的變數是指向自身的指標。2.判斷幾個自引用結構是否合法?這個結構是非法的,為什麼呢?結構裡面有包含b,b裡面有包含自己的成員b,這樣就會無休止的迴圈下去。...