C管理內(nèi)存大致可以理解為兩種,分配在棧上的,一個是分配在堆上的。
創(chuàng)新互聯(lián)主要從事成都做網(wǎng)站、成都網(wǎng)站制作、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)錦州,十載網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18982081108
臨時變量,動態(tài)變量,分配在棧上,運(yùn)行完,直接彈出棧,就沒了。
分配在堆上的內(nèi)存,釋放的時候,基本上可以理解為,指針不指這里了。也就失去了對這塊內(nèi)存的控制。其實(shí)所謂的釋放。字面意思容易讓人理解錯。
有些機(jī)器有些操作系統(tǒng),會在釋放的時候清空這段內(nèi)存,但是這種做法效率不高,但是安全,很少有機(jī)器這么做,多數(shù)都是所謂釋放,就是不讓你控制這塊內(nèi)存了而已。
一時看不明白你的代碼。一個原則是,start指向了誰。如果指向了在這個函數(shù)中定義的臨時自動型數(shù)組,那必然存在返回局部數(shù)組指針的問題,就是你說的內(nèi)存釋放問題。這樣雖然指針被返回了,但它指向的內(nèi)容已經(jīng)不受代碼控制了,很危險。但如果start指向的是在主函數(shù)中聲明的數(shù)組,或是全局或靜態(tài)數(shù)組(這個函數(shù)中定義的靜態(tài)數(shù)組也行),或者是用動態(tài)分配法獲得的內(nèi)存空間且未曾釋放,則不存在任何問題,是完全合理合法的。用動態(tài)分配法時要注意在不用時釋放內(nèi)存空間,以免造成內(nèi)存泄漏。
malloc() 函數(shù)用來動態(tài)地分配內(nèi)存空間,其原型為:void* malloc (size_t size);
說明:
【參數(shù)說明】
size 為需要分配的內(nèi)存空間的大小,以字節(jié)(Byte)計。
【函數(shù)說明】
malloc() 在堆區(qū)分配一塊指定大小的內(nèi)存空間,用來存放數(shù)據(jù)。這塊內(nèi)存空間在函數(shù)執(zhí)行完成后不會被初始化,它們的值是未知的。如果希望在分配內(nèi)存的同時進(jìn)行初始化,請使用 calloc() 函數(shù)。
【返回值】
分配成功返回指向該內(nèi)存的地址,失敗則返回 NULL。
操作:
由于申請內(nèi)存空間時可能有也可能沒有,所以需要自行判斷是否申請成功,再進(jìn)行后續(xù)操作。
如果 size 的值為 0,那么返回值會因標(biāo)準(zhǔn)庫實(shí)現(xiàn)的不同而不同,可能是 NULL,也可能不是,但返回的指針不應(yīng)該再次被引用。
注意:函數(shù)的返回值類型是 void *,void 并不是說沒有返回值或者返回空指針,而是返回的指針類型未知。所以在使用 malloc() 時通常需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換,將 void 指針轉(zhuǎn)換成我們希望的類型,例如:
#includestdlib.h
typedef int ListData;
ListData *data; ?//存儲空間基址
data = ( ListData * ) malloc( 100 * sizeof ( ListData ) );
擴(kuò)展資料
實(shí)現(xiàn)malloc的方法:
(1)數(shù)據(jù)結(jié)構(gòu)
首先我們要確定所采用的數(shù)據(jù)結(jié)構(gòu)。一個簡單可行方案是將堆內(nèi)存空間以塊的形式組織起來,每個塊由meta區(qū)和數(shù)據(jù)區(qū)組成,meta區(qū)記錄數(shù)據(jù)塊的元信息(數(shù)據(jù)區(qū)大小、空閑標(biāo)志位、指針等等)。
數(shù)據(jù)區(qū)是真實(shí)分配的內(nèi)存區(qū)域,并且數(shù)據(jù)區(qū)的第一個字節(jié)地址即為malloc返回的地址 。
(2)尋找合適的block
現(xiàn)在考慮如何在block鏈中查找合適的block。一般來說有兩種查找算法:
First fit:從頭開始,使用第一個數(shù)據(jù)區(qū)大小大于要求size的塊所謂此次分配的塊
Best fit:從頭開始,遍歷所有塊,使用數(shù)據(jù)區(qū)大小大于size且差值最小的塊作為此次分配的塊
兩種方式各有千秋,best fit有較高的內(nèi)存使用率(payload較高),而first fit具有較高的運(yùn)行效率。這里我們采用first fit算法。
(3)開辟新的block?
如果現(xiàn)有block都不能滿足size的要求,則需要在鏈表最后開辟一個新的block。
(4)分裂block?
First fit有一個比較致命的缺點(diǎn),就是可能會讓更小的size占據(jù)很大的一塊block,此時,為了提高payload,應(yīng)該在剩余數(shù)據(jù)區(qū)足夠大的情況下,將其分裂為一個新的block。
(5)malloc的實(shí)現(xiàn)
有了上面的代碼,我們就可以實(shí)現(xiàn)一個簡單的malloc.注意首先我們要定義個block鏈表的頭first_block,初始化為NULL;另外,我們需要剩余空間至少有BLOCK_SIZE+8才執(zhí)行分裂操作
由于我們需要malloc分配的數(shù)據(jù)區(qū)是按8字節(jié)對齊,所以size不為8的倍數(shù)時,我們需要將size調(diào)整為大于size的最小的8的倍數(shù)。