C語(yǔ)言基礎(chǔ)之malloc和free函數(shù)詳解
本文介紹malloc和free函數(shù)的內(nèi)容。
在C中,對(duì)內(nèi)存的管理是相當(dāng)重要。下面開(kāi)始介紹這兩個(gè)函數(shù):
一、malloc()和free()的基本概念以及基本用法:
1、函數(shù)原型及說(shuō)明:
void *malloc(long NumBytes):該函數(shù)分配了NumBytes個(gè)字節(jié),并返回了指向這塊內(nèi)存的指針。如果分配失敗,則返回一個(gè)空指針(NULL)。
關(guān)于分配失敗的原因,應(yīng)該有多種,比如說(shuō)空間不足就是一種。
void free(void *FirstByte): 該函數(shù)是將之前用malloc分配的空間還給程序或者是操作系統(tǒng),也就是釋放了這塊內(nèi)存,讓它重新得到自由。
2、函數(shù)的用法:
其實(shí)這兩個(gè)函數(shù)用起來(lái)倒不是很難,也就是malloc()之后覺(jué)得用夠了就甩了它把它給free()了,舉個(gè)簡(jiǎn)單例子:
程序代碼:
// Code... char *Ptr = NULL; Ptr = (char *)malloc(100 * sizeof(char)); if (NULL == Ptr) { exit (1); } gets(Ptr); // code... free(Ptr); Ptr = NULL; // code...
就是這樣!當(dāng)然,具體情況要具體分析以及具體解決。比如說(shuō),你定義了一個(gè)指針,在一個(gè)函數(shù)里申請(qǐng)了一塊內(nèi)存然后通過(guò)函數(shù)返回傳遞給這個(gè)指針,那么也許釋放這塊內(nèi)存這項(xiàng)工作就應(yīng)該留給其他函數(shù)了。
3、關(guān)于函數(shù)使用需要注意的一些地方:
A、申請(qǐng)了內(nèi)存空間后,必須檢查是否分配成功。
B、當(dāng)不需要再使用申請(qǐng)的內(nèi)存時(shí),記得釋放;釋放后應(yīng)該把指向這塊內(nèi)存的指針指向NULL,防止程序后面不小心使用了它。
C、這兩個(gè)函數(shù)應(yīng)該是配對(duì)。如果申請(qǐng)后不釋放就是內(nèi)存泄露;如果無(wú)故釋放那就是什么也沒(méi)有做。釋放只能一次,如果釋放兩次及兩次以上會(huì)
出現(xiàn)錯(cuò)誤(釋放空指針例外,釋放空指針其實(shí)也等于啥也沒(méi)做,所以釋放空指針釋放多少次都沒(méi)有問(wèn)題)。
D、雖然malloc()函數(shù)的類(lèi)型是(void *),任何類(lèi)型的指針都可以轉(zhuǎn)換成(void *),但是最好還是在前面進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換,因?yàn)檫@樣可以躲過(guò)一些編譯器的檢查。
現(xiàn)在進(jìn)入第二部分:
二、malloc()到底從哪里得來(lái)了內(nèi)存空間:
1、malloc()到底從哪里得到了內(nèi)存空間?答案是從堆里面獲得空間。也就是說(shuō)函數(shù)返回的指針是指向堆里面的一塊內(nèi)存。操作系統(tǒng)中有一個(gè)記錄空閑內(nèi)存地址的鏈表。當(dāng)操作系統(tǒng)收到程序的申請(qǐng)時(shí),就會(huì)遍歷該鏈表,然后就尋找第一個(gè)空間大于所申請(qǐng)空間的堆結(jié)點(diǎn),然后就將該結(jié)點(diǎn)從空閑結(jié)點(diǎn)鏈表中刪除,并將該結(jié)點(diǎn)的空間分配給程序。關(guān)于堆的知識(shí)呢可以查詢(xún)數(shù)據(jù)結(jié)構(gòu)方面的知識(shí)或查詢(xún)以前的一篇帖子C/C++堆、棧及靜態(tài)數(shù)據(jù)區(qū)詳解。這里不過(guò)多介紹。
2、在使用malloc()分配內(nèi)存空間后,一定要記得釋放內(nèi)存空間,否則就會(huì)出現(xiàn)內(nèi)存泄漏。
3、free()到底釋放了什么
free()釋放的是指針指向的內(nèi)存!注意!釋放的是內(nèi)存,不是指針!指針并沒(méi)有被釋放,指針仍然指向原來(lái)的存儲(chǔ)空間。指針是一個(gè)變量,只有程序結(jié)束時(shí)才被銷(xiāo)毀。釋放了內(nèi)存空間后,原來(lái)指向這塊空間的指針還是存在!只不過(guò)現(xiàn)在指針指向的內(nèi)容的垃圾,是未定義的,所以說(shuō)是垃圾。因此,釋放內(nèi)存后把指針指向NULL,防止指針在后面不小心又被解引用了。
三、malloc()以及free()的機(jī)制:
事實(shí)上,仔細(xì)看一下free()的函數(shù)原型,也許也會(huì)發(fā)現(xiàn)似乎很神奇,free()函數(shù)非常簡(jiǎn)單,只有一個(gè)參數(shù),只要把指向申請(qǐng)空間的指針傳遞給free()中的參數(shù)就可以完成釋放工作!這里要追蹤到malloc()的申請(qǐng)問(wèn)題了。申請(qǐng)的時(shí)候?qū)嶋H上占用的內(nèi)存要比申請(qǐng)的大。因?yàn)槌龅目臻g是用來(lái)記錄對(duì)這塊內(nèi)存的管理信息。
大多數(shù)實(shí)現(xiàn)所分配的存儲(chǔ)空間比所要求的要稍大一些,額外的空間用來(lái)記錄管理信息——分配塊的長(zhǎng)度,指向下一個(gè)分配塊的指針等等。這就意味著如果寫(xiě)過(guò)一個(gè)已分配區(qū)的尾端,則會(huì)改寫(xiě)后一塊的管理信息。這種類(lèi)型的錯(cuò)誤是災(zāi)難性的,但是因?yàn)檫@種錯(cuò)誤不會(huì)很快就暴露出來(lái),所以也就很難發(fā)現(xiàn)。將指向分配塊的指針向后移動(dòng)也可能會(huì)改寫(xiě)本塊的管理信息。
malloc()申請(qǐng)的空間實(shí)際就是分了兩個(gè)不同性質(zhì)的空間。一個(gè)就是用來(lái)記錄管理信息的空間,另外一個(gè)就是可用空間了。而用來(lái)記錄管理信息的實(shí)際上是一個(gè)結(jié)構(gòu)體。在C語(yǔ)言中,經(jīng)常用結(jié)構(gòu)來(lái)記錄信息!下面看看這個(gè)結(jié)構(gòu)體的原型:
程序代碼:
struct mem_control_block { int is_available; //一般來(lái)說(shuō)應(yīng)該是一個(gè)可用空間的首地址,但這里英文單詞卻顯示出空間是否可用的一個(gè)標(biāo)記 int size; //這是實(shí)際空間的大小 }; 所以,free()就是根據(jù)這個(gè)結(jié)構(gòu)體的信息來(lái)釋放malloc()申請(qǐng)的空間!而結(jié)構(gòu)體的兩個(gè)成員的大小我想應(yīng)該是操作系統(tǒng)的事了。 下面看看free()的源代碼 // code... void free(void *ptr) { struct mem_control_block *free; free = ptr - sizeof(struct mem_control_block); free->is_available = 1; return; }
至于malloc的源碼,有興趣的可以到網(wǎng)上找一下!
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- C語(yǔ)言詳細(xì)分析講解內(nèi)存管理malloc realloc free calloc函數(shù)的使用
- C語(yǔ)言初識(shí)動(dòng)態(tài)內(nèi)存管理malloc calloc realloc free函數(shù)
- C語(yǔ)言中動(dòng)態(tài)內(nèi)存分配malloc、calloc和realloc函數(shù)解析
- c語(yǔ)言 malloc函數(shù)詳解
- 詳解C語(yǔ)言用malloc函數(shù)申請(qǐng)二維動(dòng)態(tài)數(shù)組的實(shí)例
- c語(yǔ)言malloc函數(shù)的用法示例和意義
相關(guān)文章
基于C++17實(shí)現(xiàn)的手寫(xiě)線(xiàn)程池
本文主要介紹了基于C++17實(shí)現(xiàn)的手寫(xiě)線(xiàn)程池,自己實(shí)現(xiàn)了Any類(lèi),Semaphore類(lèi)以及Result類(lèi)的開(kāi)發(fā),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08C++詳解使用floor&ceil&round實(shí)現(xiàn)保留小數(shù)點(diǎn)后兩位
這篇文章主要介紹了C++使用floor&ceil&round實(shí)現(xiàn)保留小數(shù)點(diǎn)后兩位的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07VS2022連接sqlserver數(shù)據(jù)庫(kù)教程
本文主要介紹了VS2022連接sqlserver數(shù)據(jù)庫(kù)教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07C++中的static和const的關(guān)鍵字用法詳解
這篇文章主要介紹了C++中的static和const的關(guān)鍵字用法詳解,這是一道經(jīng)常在面試中被問(wèn)到的知識(shí),本文給大家詳細(xì)介紹下,需要的朋友可以參考下2023-06-06C語(yǔ)言從猜數(shù)字游戲中理解數(shù)據(jù)結(jié)構(gòu)
猜數(shù)字是興起于英國(guó)的益智類(lèi)小游戲,起源于20世紀(jì)中期,一般由兩個(gè)人或多人玩,也可以由一個(gè)人和電腦玩。游戲規(guī)則為一方出數(shù)字,一方猜,今天我們來(lái)用這個(gè)游戲案例理解數(shù)據(jù)結(jié)構(gòu)2022-04-04