91精品一区二区三区久久久久久_欧美一级特黄大片色_欧美一区二区人人喊爽_精品一区二区三区av

位置:51電子網 » 技術資料 » 其它綜合

Keil C動態內存管理機制分析及改進

發布時間:2007/8/29 0:00:00 訪問次數:1062

來源:單片機及嵌入式系統應用  作者:重慶電力高等專科學校 丁明亮 熊真春

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

1 相關數據結構、變量及說明
在Keil C安裝目錄下的\c5l\lib目錄下,有實現init_mempool、mallloe和free這3個函數的C源文件init_mere.c、malloc.e和free.c。下面針對keil C7.5A版,將其中與動態存儲管理相關的數據結構介紹如下;


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

在Keil C中,堆中的所有空閑內存塊是用一個單鏈表來管理的,struct_mere_即為該鏈表結點的結構,后面定義的宏AVAIL為該鏈表的首結點,為敘述方便,以下將該鏈表稱為AVAIL鏈表。



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


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


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



很明顯,從上面的if(pool==NULL){pool=1;size--;)這部分源代碼來看,如果應用程序中pool參數為空指針(pool為0)時,顯然不能直接將AVAIL,的next域的值賦為空指針的(即賦為O)。將pool的值改為1,再將size的值減l,這樣,init_mempool函數會在XDATA區中,從地址l開始,取size一1個字節作為堆來使用。如果源程序有定義在XDATA區的變量,則這些變量所占的存儲單元也可能會被當成堆空間的一部分,這無疑是有潛在風險的。

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

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

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


3 malloc函數分析
malloc函數的原形是void *malloc(unsigned intsize),size參數為需動態申請的內存塊的字節數。

malloc函數的算法是查找AVAIL鏈表中各結點next指針所指向的空閑內存塊。如果某塊的空閑字節數≥size參數,則停止查找,并從該塊進行內存分配,返回一個指向所分配內存塊的指針給應用程序。如果沒有找到符合要求的空閑內存塊,則返回空指針給應用程序。

需要注意的是,AVAIL鏈表中除首結點AVAIL外,其余各節點位于堆中各空閑內存塊開始處的一個struct__me

來源:單片機及嵌入式系統應用  作者:重慶電力高等專科學校 丁明亮 熊真春

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

1 相關數據結構、變量及說明
在Keil C安裝目錄下的\c5l\lib目錄下,有實現init_mempool、mallloe和free這3個函數的C源文件init_mere.c、malloc.e和free.c。下面針對keil C7.5A版,將其中與動態存儲管理相關的數據結構介紹如下;


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

在Keil C中,堆中的所有空閑內存塊是用一個單鏈表來管理的,struct_mere_即為該鏈表結點的結構,后面定義的宏AVAIL為該鏈表的首結點,為敘述方便,以下將該鏈表稱為AVAIL鏈表。



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


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


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



很明顯,從上面的if(pool==NULL){pool=1;size--;)這部分源代碼來看,如果應用程序中pool參數為空指針(pool為0)時,顯然不能直接將AVAIL,的next域的值賦為空指針的(即賦為O)。將pool的值改為1,再將size的值減l,這樣,init_mempool函數會在XDATA區中,從地址l開始,取size一1個字節作為堆來使用。如果源程序有定義在XDATA區的變量,則這些變量所占的存儲單元也可能會被當成堆空間的一部分,這無疑是有潛在風險的。

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

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

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


3 malloc函數分析
malloc函數的原形是void *malloc(unsigned intsize),size參數為需動態申請的內存塊的字節數。

malloc函數的算法是查找AVAIL鏈表中各結點next指針所指向的空閑內存塊。如果某塊的空閑字節數≥size參數,則停止查找,并從該塊進行內存分配,返回一個指向所分配內存塊的指針給應用程序。如果沒有找到符合要求的空閑內存塊,則返回空指針給應用程序。

需要注意的是,AVAIL鏈表中除首結點AVAIL外,其余各節點位于堆中各空閑內存塊開始處的一個struct__me

相關IC型號

熱門點擊

 

推薦技術資料

羅盤誤差及補償
    造成羅盤誤差的主要因素有傳感器誤差、其他磁材料干擾等。... [詳細]
版權所有:51dzw.COM
深圳服務熱線:13751165337  13692101218
粵ICP備09112631號-6(miitbeian.gov.cn)
公網安備44030402000607
深圳市碧威特網絡技術有限公司
付款方式


 復制成功!
贺州市| 乌审旗| 武陟县| 定州市| 金华市| 荣昌县| 连山| 太湖县| 随州市| 苗栗市| 哈尔滨市| 习水县| 闵行区| 绥滨县| 龙海市| 万年县| 顺义区| 武定县| 象山县| 大同市| 项城市| 疏勒县| 上高县| 玉林市| 务川| 大同县| 和林格尔县| 元阳县| 红河县| 亚东县| 民权县| 竹山县| 安吉县| 聂荣县| 邹城市| 遂昌县| 苍南县| 凤冈县| 枣阳市| 西安市| 资溪县|