<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 元件/連接器 > 設計應用 > Keil C動(dòng)態(tài)內存管理機制分析及改進(jìn)

Keil C動(dòng)態(tài)內存管理機制分析及改進(jìn)

——
作者:重慶電力高等專(zhuān)科學(xué)校 丁明亮 熊真春 時(shí)間:2007-07-04 來(lái)源:?jiǎn)纹瑱C及嵌入式系統應用 收藏
 Keil C是常用的嵌入式系統編程工具,它通過(guò)init_mempool、mallloe、free等函數,提供了動(dòng)態(tài)存儲管理等功能。本文通過(guò)對init_mempool、mallloe和free這3個(gè)KeilC庫函數源代碼的分析,揭示其實(shí)現的原理和方法,并對其中的不足作了改進(jìn),以使Keil C編程人員更好地應用動(dòng)態(tài)存儲管理。

  1 相關(guān)數據結構、變量及說(shuō)明

  在Keil C安裝目錄下的\c5l\lib目錄下,有實(shí)現init_mempool、mallloe和free這3個(gè)函數的C源文件init_mere.c、malloc.e和free.c。下面針對keil C7.5A版,將其中與動(dòng)態(tài)存儲管理相關(guān)的數據結構介紹如下:

與動(dòng)態(tài)存儲管理相關(guān)的數據結構

  該結構的next指向堆中的下一空閑內存塊,len表示該空閑塊除去該塊首部的struct__mem__結構所占的字節數后,該塊實(shí)際可用的字節數。由于next是一個(gè)指向XDATA區的指針,故在Keil C中應用程序所定義的堆空間應在XDATA段中定義。

  在Keil C中,堆中的所有空閑內存塊是用一個(gè)單鏈表來(lái)管理的,struct_mere_即為該鏈表結點(diǎn)的結構,后面定義的宏AVAIL為該鏈表的首結點(diǎn),為敘述方便,以下將該鏈表稱(chēng)為AVAIL鏈表。

AVAIL鏈表

  #define AVAIL(__meM_avaiL_[O])

  全局數組__meM_ avail_實(shí)際也是struct__mem__類(lèi)型,__mem_avail__[O]的next指向堆中首塊空閑塊。如果堆中已無(wú)空閑內存塊,則__mem_avail__[0]的next為NULL(0值)。為使程序代碼簡(jiǎn)潔,定義了宏AVAIL來(lái)代替__mem_avail__[O]。

  2 init_mempool函數剖析

  函數int_mempool(void_MALLOC_MEM_*pool,unsigned int size)失敗時(shí)將返回0,成功則返回一1,參數pool指向應用程序定義的堆空間,參數size為堆空間的字節數。如果應用程序提供的堆空間太小(size的值太小),將失去實(shí)際意義,故函數將返回0表示失敗。當size參數足夠大,則會(huì )初始化AVAIL(即_mem_avail__[O]),使其next域指向pool參數所指向的堆空間,len域為pool參數所指向的堆空間的總字節數size。其在KeilC 7.5A庫中init_mem.C的源代碼如下:

C的源代碼

  在成功執行init_mempool函數后,將得到如圖1所示的一個(gè)數據結構。另外,鏈首結點(diǎn)AVAIL的len域記錄了整個(gè)堆的字節數。鏈首AVAIL結點(diǎn)的next域指向的是首塊空閑塊,當經(jīng)過(guò)多次的malloe函數而堆中投有空閑內存塊時(shí),AVAIL結點(diǎn)的next域將為NULL值。

數據結構

  很明顯,從上面的if(pool==NULL){pool=1;size--;)這部分源代碼來(lái)看,如果應用程序中pool參數為空指針(pool為0)

 
時(shí),顯然不能直接將AVAIL,的next域的值賦為空指針的(即賦為O)。將pool的值改為1,再將size的值減l,這樣,init_mempool函數會(huì )在XDATA區中,從地址l開(kāi)始,取size一1個(gè)字節作為堆來(lái)使用。如果源程序有定義在XDATA區的變量,則這些變量所占的存儲單元也可能會(huì )被當成堆空間的一部分,這無(wú)疑是有潛在風(fēng)險的。

  部分程序員在調用init_mempool函數時(shí),習慣將pool參數設為一個(gè)形如0xAAAA數字表示的絕對地址,如果不加特別防范,也是不妥的,因為Keil C可能會(huì )在此方式指定的堆空間中分配臨時(shí)變量。好的習慣是定義一個(gè)字節數組作為堆空間,再將數組名作為pool參數調用init_mempool函數。

  在Keil C的聯(lián)機文檔中,指明了init_mempool在應用程序中只能被調用一次,那么,如果多次調用該函數又會(huì )有什么后果呢?從該函數的源代碼來(lái)分析,多次調用init_mempoo1函數,會(huì )導致重新初始化首結點(diǎn)AVAIL的next域和len域的值,將使AVAIL鏈表中的原有管理信息丟失,從而導致一些很難診斷的問(wèn)題。

  對此問(wèn)題,可采用如下保護措施。當發(fā)現AVAIL鏈表中已有管理信息時(shí),則返回失敗標志,函數直接返回。具體的方法是檢查AVAIL結點(diǎn)的len域,由于其被初始化為零,如果發(fā)現其值非零,則表明init_mempool函數已被成功調用過(guò),此時(shí)函數直接返回。

 Keil C是常用的嵌入式系統編程工具,它通過(guò)init_mempool、mallloe、free等函數,提供了動(dòng)態(tài)存儲管理等功能。本文通過(guò)對init_mempool、mallloe和free這3個(gè)KeilC庫函數源代碼的分析,揭示其實(shí)現的原理和方法,并對其中的不足作了改進(jìn),以使Keil C編程人員更好地應用動(dòng)態(tài)存儲管理。

  1 相關(guān)數據結構、變量及說(shuō)明

  在Keil C安裝目錄下的\c5l\lib目錄下,有實(shí)現init_mempool、mallloe和free這3個(gè)函數的C源文件init_mere.c、malloc.e和free.c。下面針對keil C7.5A版,將其中與動(dòng)態(tài)存儲管理相關(guān)的數據結構介紹如下:

與動(dòng)態(tài)存儲管理相關(guān)的數據結構

  該結構的next指向堆中的下一空閑內存塊,len表示該空閑塊除去該塊首部的struct__mem__結構所占的字節數后,該塊實(shí)際可用的字節數。由于next是一個(gè)指向XDATA區的指針,故在Keil C中應用程序所定義的堆空間應在XDATA段中定義。

  在Keil C中,堆中的所有空閑內存塊是用一個(gè)單鏈表來(lái)管理的,struct_mere_即為該鏈表結點(diǎn)的結構,后面定義的宏AVAIL為該鏈表的首結點(diǎn),為敘述方便,以下將該鏈表稱(chēng)為AVAIL鏈表。

AVAIL鏈表

  #define AVAIL(__meM_avaiL_[O])

  全局數組__meM_ avail_實(shí)際也是struct__mem__類(lèi)型,__mem_avail__[O]的next指向堆中首塊空閑塊。如果堆中已無(wú)空閑內存塊,則__mem_avail__[0]的next為NULL(0值)。為使程序代碼簡(jiǎn)潔,定義了宏AVAIL來(lái)代替__mem_avail__[O]。

  2 init_mempool函數剖析

  函數int_mempool(void_MALLOC_MEM_*pool,unsigned int size)失敗時(shí)將返回0,成功則返回一1,參數pool指向應用程序定義的堆空間,參數size為堆空間的字節數。如果應用程序提供的堆空間太小(size的值太小),將失去實(shí)際意義,故函數將返回0表示失敗。當size參數足夠大,則會(huì )初始化AVAIL(即_mem_avail__[O]),使其next域指向pool參數所指向的堆空間,len域為pool參數所指向的堆空間的總字節數size。其在KeilC 7.5A庫中init_mem.C的源代碼如下:

C的源代碼

  在成功執行init_mempool函數后,將得到如圖1所示的一個(gè)數據結構。另外,鏈首結點(diǎn)AVAIL的len域記錄了整個(gè)堆的字節數。鏈首AVAIL結點(diǎn)的next域指向的是首塊空閑塊,當經(jīng)過(guò)多次的malloe函數而堆中投有空閑內存塊時(shí),AVAIL結點(diǎn)的next域將為NULL值。

數據結構

  很明顯,從上面的if(pool==NULL){pool=1;size--;)這部分源代碼來(lái)看,如果應用程序中pool參數為空指針(pool為0)

 
時(shí),顯然不能直接將AVAIL,的next域的值賦為空指針的(即賦為O)。將pool的值改為1,再將size的值減l,這樣,init_mempool函數會(huì )在XDATA區中,從地址l開(kāi)始,取size一1個(gè)字節作為堆來(lái)使用。如果源程序有定義在XDATA區的變量,則這些變量所占的存儲單元也可能會(huì )被當成堆空間的一部分,這無(wú)疑是有潛在風(fēng)險的。

  部分程序員在調用init_mempool函數時(shí),習慣將pool參數設為一個(gè)形如0xAAAA數字表示的絕對地址,如果不加特別防范,也是不妥的,因為Keil C可能會(huì )在此方式指定的堆空間中分配臨時(shí)變量。好的習慣是定義一個(gè)字節數組作為堆空間,再將數組名作為pool參數調用init_mempool函數。

  在Keil C的聯(lián)機文檔中,指明了init_mempool在應用程序中只能被調用一次,那么,如果多次調用該函數又會(huì )有什么后果呢?從該函數的源代碼來(lái)分析,多次調用init_mempoo1函數,會(huì )導致重新初始化首結點(diǎn)AVAIL的next域和len域的值,將使AVAIL鏈表中的原有管理信息丟失,從而導致一些很難診斷的問(wèn)題。

  對此問(wèn)題,可采用如下保護措施。當發(fā)現AVAIL鏈表中已有管理信息時(shí),則返回失敗標志,函數直接返回。具體的方法是檢查AVAIL結點(diǎn)的len域,由于其被初始化為零,如果發(fā)現其值非零,則表明init_mempool函數已被成功調用過(guò),此時(shí)函數直接返回。



關(guān)鍵詞: 存儲器

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>