嵌入式作業系統核心原理和開發(基於鏈表節點的記憶體配置演算法)

來源:互聯網
上載者:User

【 聲明:著作權,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】

    連結節點的記憶體配置方法,其實就是一種按需分配的記憶體配置方法。簡單一點說,就是你需要多少記憶體,我就給你多少記憶體。當然,為了把分配的記憶體都連起來,我們還需要對分配節點進行管理記錄。就比如下面這個資料結構,

typedef struct _MNG_NODE{    struct _MNG_NODE* next;    unsigned int size;}MNG_NODE;

    其中,next節點記錄了下面一個節點的位置,size表示了當前節點下方的記憶體大小。在記憶體初始化的時候,我們預設起始記憶體塊就是一個大節點,其中前面8個位元組就是上面的內容。此時,如果需要進行記憶體拆分,我們就可以把一個節點拆分成兩個節點,就比如這樣,

    pNew = (MNG_NODE*)((char*)pOld + sizeof(MNG_NODE) + pOld->size - (sizeof(MNG_NODE) + size));

    pNew代表了新產生的結點,pOld代表了原來的節點。為了不影響原來的節點,每次分配新節點的時候必須在記憶體的高端位置進行分配。這樣也保證了原來節點結構和資料的連貫性。當然分配結束之後,只需要對節點的的size重新進行一下賦值就可以了。

    pNew->size = size;    pOld->size -= sizeof(MNG_NODE) + size;

    此時pOld節點會歸還到pFreeList當中,而產生的pNew節點則插入到pAllocList當中。其中,pFreeList表示當前的空閑節點,pAllocList表示已指派節點。相比較而言,記憶體的釋放就比較簡單,只需要把節點找出來插入到pAllocList中即可。當然,此時如果能做一下前後節點的合并工作就更好了。

    不過,上面描述的步驟只是就比較重要知識點講解了一下。在真正設計代碼的過程中還需要考慮到節點的尋找、記憶體大小的判斷、資料初始化、鏈表插入、測試案例編寫等工作,步驟會稍微繁瑣一下。下面我們就給出完整的程式碼範例。

/**************************************************      malloc & free in link node algorithm**************************************************/#include <string.h>#include <malloc.h>/**************************************************           struct definition**************************************************/typedef struct _MNG_NODE{    struct _MNG_NODE* next;    unsigned int size;}MNG_NODE;/**************************************************           global variable declaration**************************************************/#define MEM_BUFFER_LENGTH   (0x1 << 24)static void* pGlbData;static MNG_NODE* pFreeList;static MNG_NODE* pAllocList;/************************************************** function: add node into headlist**************************************************/static void add_node_into_list_head(MNG_NODE* pNode, MNG_NODE** ppList){    pNode->next = *ppList;    *ppList = pNode;   }/************************************************** function: find best fit node**************************************************/static MNG_NODE* find_best_fit_node(unsigned int size){    MNG_NODE* pCur = pFreeList;    MNG_NODE* pPre = pCur;    while(pCur && pCur->size < (size + sizeof(MNG_NODE)))    {         pPre = pCur;        pCur = pCur->next;    }       if(NULL == pCur)        return NULL;    if(pFreeList == pCur)        pFreeList = pFreeList->next;    else        pPre->next = pCur->next;    return pCur;}/************************************************** function: implement memory allocation**************************************************/static void* _mem_malloc(unsigned int size){    MNG_NODE* pOld;    MNG_NODE* pNew;    pOld = find_best_fit_node(size);    if(NULL == pOld)        return NULL;    pNew = (MNG_NODE*)((char*)pOld + sizeof(MNG_NODE) + pOld->size - (sizeof(MNG_NODE) + size));    pNew->size = size;    pOld->size -= sizeof(MNG_NODE) + size;    add_node_into_list_head(pOld, &pFreeList);    add_node_into_list_head(pNew, &pAllocList);    return (void*)((char*)pNew + sizeof(MNG_NODE));}/************************************************** function: memory allocation**************************************************/void* mem_malloc(unsigned int size){    if(0 == size)        return NULL;    if(size > (MEM_BUFFER_LENGTH - sizeof(MNG_NODE)))        return NULL;    return _mem_malloc(size);}/************************************************** function: find previous node **************************************************/static MNG_NODE* find_previous_node(MNG_NODE* pNode){    MNG_NODE* pFind = pAllocList;    MNG_NODE* pPre = NULL;        while(pFind && pFind != pNode)    {        pPre = pFind;        pFind = pFind->next;    }    if(NULL == pFind)        return NULL;    return pPre;}/************************************************** function: implement memory free**************************************************/static void _mem_free(MNG_NODE* pNode){    MNG_NODE* pPreNode;    if(pNode == pAllocList)    {        pAllocList = pAllocList->next;        add_node_into_list_head(pNode, &pFreeList);        return;    }        pPreNode = find_previous_node(pNode);    if(NULL == pPreNode)        return;    pPreNode->next = pNode->next;    add_node_into_list_head(pNode, &pFreeList);    return;}/************************************************** function: free memory function**************************************************/void mem_free(void* pData){    if(NULL == pData)        return;    if(pData < pGlbData || pData >= (void*)((char*)pGlbData + MEM_BUFFER_LENGTH))        return;    _mem_free(pData - sizeof(MNG_NODE));}/************************************************** function: get memory buffer**************************************************/void mem_init(){    pGlbData = (void*)malloc(MEM_BUFFER_LENGTH);    if(NULL == pGlbData)        return;    memset(pGlbData, 0, MEM_BUFFER_LENGTH);    pFreeList = (MNG_NODE*)pGlbData;    pFreeList->size = MEM_BUFFER_LENGTH - sizeof(MNG_NODE);    pAllocList = NULL;}/************************************************** function: free memory buffer**************************************************/void mem_exit(){    if(NULL != pGlbData)        free(pGlbData);       pFreeList = NULL;    pAllocList = NULL;}/************************************************** function: file starts here**************************************************/int main(int argc, char* argv[]){    mem_init();    mem_exit();    return 1;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.