《內(nèi)存池設(shè)計(jì)》word版

《內(nèi)存池設(shè)計(jì)》word版

ID:28959383

大?。?90.04 KB

頁數(shù):20頁

時(shí)間:2018-12-15

《內(nèi)存池設(shè)計(jì)》word版_第1頁
《內(nèi)存池設(shè)計(jì)》word版_第2頁
《內(nèi)存池設(shè)計(jì)》word版_第3頁
《內(nèi)存池設(shè)計(jì)》word版_第4頁
《內(nèi)存池設(shè)計(jì)》word版_第5頁
資源描述:

《《內(nèi)存池設(shè)計(jì)》word版》由會員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫

1、C++內(nèi)存池設(shè)計(jì)在項(xiàng)目中進(jìn)程要對變量和對象分配空間,由于頻繁的使用new和delete很消耗程序的運(yùn)行時(shí)間,而且容易產(chǎn)生各種內(nèi)存泄露,內(nèi)存釋放錯(cuò)誤等問題。為此,需要設(shè)計(jì)一個(gè)通用的內(nèi)存池來完成相關(guān)的分配和釋放的工作。建立內(nèi)存池:首先向系統(tǒng)申請一塊內(nèi)存,這塊內(nèi)存的大小由使用者根據(jù)需要設(shè)置初始內(nèi)存大小。定義一個(gè)如下面代碼所示的雙向鏈表,將從系統(tǒng)分配的內(nèi)存分為若干塊。使用雙向鏈表方便指針向前和向后遍歷查找。鏈表中*Data指向了系統(tǒng)分配的內(nèi)存,pUser使用二級指針保存了內(nèi)存申請者的地址,方便以后系統(tǒng)內(nèi)存塊更改,

2、改變申請者的指向。后面會詳細(xì)介紹。將雙向鏈表指向指向內(nèi)存如下所示:假設(shè)內(nèi)存池初始塊數(shù)為4塊,每塊的大小為100個(gè)字節(jié),則向系統(tǒng)申請400個(gè)字節(jié)的內(nèi)存塊,每塊的大小為100字節(jié)。之后使用雙向鏈表DATA指針指向內(nèi)存塊,每個(gè)指針能分配的大小如圖所示從大到小遞減。對象內(nèi)存分配:對內(nèi)存的鏈表指針分配好后,用戶可以使用內(nèi)存池進(jìn)行內(nèi)存分配,對于用戶的內(nèi)存分配有兩種情況,一種是在現(xiàn)有的內(nèi)存池中能找到合適的內(nèi)存塊,另一種情況是現(xiàn)有內(nèi)的內(nèi)存池沒有足夠的內(nèi)存塊來分配,需要重新向系統(tǒng)申請內(nèi)存來滿足用戶的需求。下面分別就這兩種內(nèi)

3、存分配情況進(jìn)行說明:情況1內(nèi)存池有足夠的內(nèi)存塊進(jìn)行分配假設(shè)用戶申請了240個(gè)字節(jié)的內(nèi)存空間,內(nèi)存池現(xiàn)在有四個(gè)內(nèi)存塊空閑,每個(gè)內(nèi)存塊的大小為100字節(jié),那么內(nèi)存池將會給用戶取整分配三個(gè)內(nèi)存塊。如上圖所示,并將指向400內(nèi)存塊的指針的DATE返回給用戶使用。情況2內(nèi)存池沒有足夠的內(nèi)存塊進(jìn)行分配接著上圖,假設(shè)用戶現(xiàn)在要接著分別300字節(jié)的內(nèi)存空間,現(xiàn)有內(nèi)存池的大小已經(jīng)不能滿足,因此需要擴(kuò)大現(xiàn)有的內(nèi)存池使用大小??紤]到由于分配給用戶的內(nèi)存空間必須要是連續(xù)的內(nèi)存塊,因此這個(gè)連續(xù)的內(nèi)存塊越大,能分配給用戶的內(nèi)存就多。

4、因此使用C語言的realloc函數(shù)來滿足要求。函數(shù)簡介原型:externvoid*realloc(void*mem_address,unsignedintnewsize);語法:指針名=(數(shù)據(jù)類型*)realloc(要改變內(nèi)存大小的指針名,新的大?。?。//新的大小一定要大于原來的大小,不然的話會導(dǎo)致數(shù)據(jù)丟失!頭文件:#include有些編譯器需要#include,在TC2.0中可以使用alloc.h頭文件功能:先判斷當(dāng)前的指針是否有足夠的連續(xù)空間,如果有,擴(kuò)大mem

5、_address指向的地址,并且將mem_address返回,如果空間不夠,先按照newsize指定的大小分配空間,將原有數(shù)據(jù)從頭到尾拷貝到新分配的內(nèi)存區(qū)域,而后釋放原來mem_address所指內(nèi)存區(qū)域(注意:原來指針是自動(dòng)釋放,不需要使用free),同時(shí)返回新分配的內(nèi)存區(qū)域的首地址。即重新分配存儲器塊的地址。返回值:如果重新分配成功則返回指向被分配內(nèi)存的指針,否則返回空指針NULL。由realloc函數(shù)定義可知,新分配的內(nèi)存空間可能是在原有的內(nèi)存基礎(chǔ)上擴(kuò)充,還有可能是在另外的一個(gè)地方新開辟一塊內(nèi)存。無

6、論哪種情況多要對新加的內(nèi)存進(jìn)行指針指向分配。并且對于第二種情況,會出現(xiàn)的問題是原有的指針全都失效。因?yàn)樵兄赶虻膬?nèi)存已經(jīng)不存在了,因此指向它的指針將失效,原有分配的對象也將失效。為了解決這個(gè)問題,在新分配內(nèi)存后需要重定向原有的指針,并且使用二級指針改變已經(jīng)分配了對象的地址的指向,使它指向新內(nèi)存。重定向原有內(nèi)存的指針的指向,和已經(jīng)分配了內(nèi)存的對象的指向。對象釋放內(nèi)存:假如先前的申請了250個(gè)字節(jié)分配了三個(gè)內(nèi)存塊的用戶釋放了內(nèi)存,這時(shí)鏈表指針向后查找直到找到第一個(gè)被使用的內(nèi)存塊,或鏈表結(jié)尾。之后在先前查找直到

7、找到前面第一個(gè)被使用的內(nèi)存塊或者是頭指針,之后更新這個(gè)區(qū)間段內(nèi)存塊的大小。釋放內(nèi)存池:首先釋放向系統(tǒng)申請的內(nèi)存塊,之后在清空所有的雙向鏈表。釋放向系統(tǒng)申請的內(nèi)存釋放雙向鏈表。后續(xù)改進(jìn):1,需要對多線程的支持,目前的內(nèi)存池還只能在單線程的環(huán)境下運(yùn)行。2,如果之前得到內(nèi)存的對象,在新內(nèi)存分配前有指針復(fù)制操作,原有對象可以通過保存的指針地址進(jìn)行重定向,但是之前分別的對象不能保證。引進(jìn)對于分配的對象盡量不要使用指針復(fù)制。如果一定需要這么做,那就在每次使用前,在重定向一下。重新進(jìn)行一次復(fù)制操作(保險(xiǎn)起見,不知道我的

8、表述是否清楚明白)。源代碼:?頭文件鏈表節(jié)點(diǎn)的定義#include#include#include#includeusingnamespacestd;namespaceMemePool{typedefunsignedcharEigthByte;//內(nèi)存池的默認(rèn)大小和分配節(jié)點(diǎn)的默認(rèn)大小staticconstsize_tDEFAULTMEMEPOOLSIZ

當(dāng)前文檔最多預(yù)覽五頁,下載文檔查看全文

此文檔下載收益歸作者所有

當(dāng)前文檔最多預(yù)覽五頁,下載文檔查看全文
溫馨提示:
1. 部分包含數(shù)學(xué)公式或PPT動(dòng)畫的文件,查看預(yù)覽時(shí)可能會顯示錯(cuò)亂或異常,文件下載后無此問題,請放心下載。
2. 本文檔由用戶上傳,版權(quán)歸屬用戶,天天文庫負(fù)責(zé)整理代發(fā)布。如果您對本文檔版權(quán)有爭議請及時(shí)聯(lián)系客服。
3. 下載前請仔細(xì)閱讀文檔內(nèi)容,確認(rèn)文檔內(nèi)容符合您的需求后進(jìn)行下載,若出現(xiàn)內(nèi)容與標(biāo)題不符可向本站投訴處理。
4. 下載文檔時(shí)可能由于網(wǎng)絡(luò)波動(dòng)等原因無法下載或下載錯(cuò)誤,付費(fèi)完成后未能成功下載的用戶請聯(lián)系客服處理。