• 内存管理


      你是否好奇过Malloc和Free内部是如何实现?本文为你揭秘。

      动态内存管理分为定长内存管理和变成内存管理。定长内存管理每次都分配固定长度内存,算法复杂度是O(1);变长内存管理是申请多少字节就分配多少直接,算法复杂度是O(n)。为了追求时间和空间的平衡,因此本文综合使用定长和变长内存管理。

    定长内存管理

    void InitFMemory(unsigned char *mem, unsigned int size)
    {
        int             num = 0;
        int             i = 0;
        FMemNode         *current = NULL;
        FMemNode         *next = NULL;
        
        num = size / (sizeof(FMemNode) + F_MEMORY_LENGTH);
        
        gFMemList.listHead = (FMemNode *)mem;
        gFMemList.nodeBase = mem;
        gFMemList.memBase = mem + num * sizeof(FMemNode);
        gFMemList.num = num;
    
        for(i = 0; i < num - 1; i++)
        {
            current = (FMemNode *)(gFMemList.nodeBase + (sizeof(FMemNode) * i));
            next = (FMemNode *)(gFMemList.nodeBase + (sizeof(FMemNode) * (i + 1)));
            current->next = next;
        }
    
        ((FMemNode *)(gFMemList.nodeBase + (sizeof(FMemNode) * i)))->next = NULL;
        
        return;
    }
    
    unsigned char* FMalloc()
    {
        unsigned char     *ret = NULL;
        unsigned int     index = 0;
        FMemNode         *pos = NULL;
        
        if(NULL != gFMemList.listHead)
        {
            pos = gFMemList.listHead;
            gFMemList.listHead = pos->next;
            
            index = ((unsigned char *)pos - (unsigned char *)(gFMemList.nodeBase)) / sizeof(FMemNode);
            ret = (unsigned char *)(gFMemList.memBase) + index * F_MEMORY_LENGTH;
            pos->next = (FMemNode *)ret;
        }
        
        return ret;
    }
    
    int FFree(unsigned char *mem)
    {
        unsigned int     index = 0;
        FMemNode         *pos = NULL;
        
        index = (mem - gFMemList.memBase) / F_MEMORY_LENGTH;
        pos = (FMemNode *)(gFMemList.nodeBase + index * sizeof(FMemNode));
        if(mem == (unsigned char *)(pos->next))
        {
            pos->next = gFMemList.listHead;
            gFMemList.listHead = pos;
            return 0;
        }
        
        return 1;
    }
    
    void ShowFMemInfo()
    {
        FMemNode         *pos = gFMemList.listHead;
        unsigned int    freeNum = 0;
        
        while(NULL != pos)
        {
            freeNum++;
            pos = pos->next;
        }
        
        printf("Fix Memory info:\n");
        printf("totoal = %d, free = %d\n", gFMemList.num, freeNum);
    }

    变成内存管理

    void InitVmemory(unsigned char *mem, unsigned int size)
    {
        VMemNode        *pNode = NULL;
        
        init_list_head(&gVMemList);
        
        pNode = (VMemNode *)mem;
        pNode->freeSize = size;
        pNode->UsedSize = 0;
        pNode->mem = mem + sizeof(VMemNode);
        init_list_head(&pNode->list);
        
        list_add_tail(&pNode->list, &gVMemList);
    }
    unsigned char* VMalloc(unsigned int size)
    {
        unsigned char     *ret = NULL;
        List            *pos = NULL;
        VMemNode        *pNode = NULL;
        VMemNode        *pNewNode = NULL;
        
        list_for_each(pos, &gVMemList)
        {
            pNode = (VMemNode *)pos;
            if(pNode->freeSize >= (size + sizeof(VMemNode)))
            {
                pNewNode = (VMemNode *)(pNode->mem + pNode->freeSize + pNode->UsedSize - (size + sizeof(VMemNode)));
                pNewNode->freeSize = 0;
                pNewNode->UsedSize = size;
                pNewNode->mem = (unsigned char*)(pNewNode + 1);
                init_list_head(&pNewNode->list);
                list_add_tail(&pNewNode->list, pNode->list.next);
                
                pNode->freeSize = pNode->freeSize - (size + sizeof(VMemNode));
                
                ret = pNewNode->mem;
                
                break;
            }
        }
        
        return ret;
    }
    
    void VFree(unsigned char *mem)
    {
        List            *pos = NULL;
        VMemNode        *pNode = NULL;
        VMemNode        *pPreNode = NULL;
        
        list_for_each(pos, &gVMemList)
        {
            pNode = (VMemNode *)pos;
            if(pNode->mem == mem)
            {
                pPreNode = (VMemNode *)(pos->prev);
                pPreNode->freeSize = pPreNode->freeSize + pNode->freeSize + pNode->UsedSize + sizeof(VMemNode);
                list_del(&pNode->list);
                break;
            }
        }
        
        return;
    }
    
    void ShowVMemInfo()
    {
        List            *pos = NULL;
        VMemNode        *pNode = NULL;
        unsigned int    num = 0;
        
        printf("Var Memory info:\n");
        list_for_each(pos, &gVMemList)
        {
            pNode = (VMemNode *)pos;
            num++;
            printf("num = %d, ptr = 0x%x, freeSize = %d, usedSize = %d\n", num, pNode->mem, pNode->freeSize, pNode->UsedSize);
        }
        
        return;
    }

    二者综合使用

    void InitMemory(unsigned char *mem, unsigned int size)
    {
        unsigned char *fmem = NULL;
        unsigned char *vmem = NULL;
        unsigned int  fsize = 0;
        unsigned int  vsize = 0;
        
        fsize = size / 2;
        vsize = size - fsize;
        
        fmem = mem;
        vmem = mem + fsize;
        
        InitFMemory(fmem, fsize);
        InitVmemory(vmem, vsize);
        
        return;
    }
    
    unsigned char* Malloc(unsigned int size)
    {
        unsigned char *mem = NULL;
        
        if(size <= F_MEMORY_LENGTH)
        {
            mem = FMalloc();
        }
        
        if(NULL == mem)
        {
            mem = VMalloc(size);
        }
        
        return mem;
    }
    
    void Free(unsigned char *mem)
    {
        if(FFree(mem))
        {
            VFree(mem);
        }
        
        return;
    }
    
    void ShowMemInfo()
    {
        printf("-----------Memory Info-----------\n");
        ShowFMemInfo();
        ShowVMemInfo();
    }

    测试代码

    #include <stdio.h>
    #include "memory.h"
    
    int main()
    {
        unsigned char data[1024 * 1024] = {0};
        
        InitMemory(data, sizeof(data));
        
        unsigned char *p1 = Malloc(20);
        unsigned char *p2 = Malloc(200);
        unsigned char *p3 = Malloc(16);
        
        ShowMemInfo();
        
        Free(p1);
        Free(p2);
        Free(p3);
        
        ShowMemInfo();
        
        return 0;
    }
  • 相关阅读:
    [java] 深入理解内部类: inner-classes
    [java] 更好的书写equals方法-汇率换算器的实现(4)
    [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3
    [java] jsoup使用简介-汇率换算器实现-插曲2
    [java] 汇率换算器实现(3)
    [java] 汇率换算器实现-插曲1-正则表达式(1)
    [java] 汇率换算器实现(2)
    [java] 汇率换算器实现(1)
    [Basic] The most basic things about java
    电路相关知识–读<<继电器是如何成为CPU的>>
  • 原文地址:https://www.cnblogs.com/chusiyong/p/15719455.html
Copyright © 2020-2023  润新知