embed\vs2008_ucos\bsp\bspmem.h.c 动态内存申请与释放

来源:互联网 发布:vc socket异步编程 编辑:程序博客网 时间:2024/06/06 04:03

/*****************************************************************************************
                                内存栈动态申请与释放
文件:bspmem.h
编者:张永辉 2013年7月30日
*****************************************************************************************/
#ifndef _BSP_H_
#define _BSP_H_
#include "\embed\source\lib\basetype.h"
//*********************************配置***************************************************
//***************************************函数声明*****************************************
int   BspMemInit(void);
int   BspMemFreeSize(void);
int   BspMemUsedSize(void);
void *BspMemMalloc(u32 size);
void  BspMemFree(void* ptr);
//****************************************************************************************
#endif
/*****************************************************************************************
                            内存分配
文件:bspmem.c
编者:张永辉
平台:vs2008
参考:程序员的自我修养。。
*****************************************************************************************/
#define _BSP_C_
#include<Windows.h>
#include<process.h>                     //_beginthread
#include "bsp.h"
#include "bspdbg.h"
//****************************************************************************************
void *MathMemSet(void *ptr,char c,unsigned int len)
{
    void * start = ptr;
    if (ptr == 0)
    {
        return (void*)0;
    }
    while(len--)
    {
        *(char*)ptr = (char)c;
        ptr = (char*)ptr+1;
    }
    return start;
}
/*****************************************************************************************
                                内存定义
*****************************************************************************************/
//大小及空间
#define     HEAP_ALL_SIZE 1024          //总大小
int         memblockcnt = 0;            //已经使用了的块数目
static      u8 mem[HEAP_ALL_SIZE];      //静态的内存空间,或指针也可以
//用于描述一个内存块  占16个字节
typedef struct _heap_header
{
    enum
    {
        BLOCK_FREE = 0XABABABAB,        //此块未被使用标志
        BLOCK_USED = 0XCDCDCDCD         //此块已被使用标志
    }type;
    u32 size;                           //此块的大小,包括头部
    struct _heap_header *next;          //下一个块
    struct _heap_header *prev;          //上一个块
}heap_header;

#define     ADDR_ADD(a,o)   (((char*)(a)) + o)      //地址+偏移
static      heap_header*    list_head = NULL;       //头指针
#define     HEADER_SIZE     (sizeof(heap_header))
/*****************************************************************************************
                                内存分配与释放
*****************************************************************************************/
//初始化
int BspMemInit(void)
{
    list_head = (heap_header*)mem;
    list_head->size = HEAP_ALL_SIZE;        //第一块空间,是最大的
    list_head->type = BLOCK_FREE;           //是空闲空间
    list_head->next = NULL;
    list_head->prev = NULL;
    memblockcnt = 0;
    return 0;
}
//分配
void *BspMemMalloc(u32 size)
{
    heap_header *header = NULL;
    if (size == 0)
    {
        return NULL;
    }
    //遍历查找空块
    header = list_head;
    while(header != NULL)
    {
        if(header->type == BLOCK_USED)
        {
            header = header->next;
            continue;
        }
        //只有中间的块刚好够用
        if((header->size >= size + HEADER_SIZE) && (header->size < size + HEADER_SIZE * 2))
        {
            header->type = BLOCK_USED;
            memblockcnt++;
            return ADDR_ADD(header,HEADER_SIZE);
        }
        //有足够空间,分割
        if(header->size >= size + HEADER_SIZE*2)
        {
            //下一个块的头部
            heap_header* next = (heap_header*)ADDR_ADD(header,size + HEADER_SIZE);
            next->prev = header;
            next->next = header->next;          //不是NLL
            next->type = BLOCK_FREE;
            next->size = header->size - (size + HEADER_SIZE);

            //改变本次块的头部
            header->next = next;
            header->size = size + HEADER_SIZE;
            header->type = BLOCK_USED;
            memblockcnt++;
            return ADDR_ADD(header,HEADER_SIZE);
        }
        header = header->next;
    }
    return 0;
}
//释放空间
void BspMemFree(void* ptr)
{
    //找到头部
    heap_header* header = (heap_header*)ADDR_ADD(ptr, (0-HEADER_SIZE));

    if(header->type != BLOCK_USED)
    {
        return;
    }
    header->type = BLOCK_FREE;

    //前面的为空则合并
    if (header->prev != NULL && header->prev->type == BLOCK_FREE)
    {
        header->prev->next = header->next;
        if (header->next != NULL)
        {
            header->next->prev = header->prev;
        }
        header->prev->size += header->size;
        header = header->prev;
        memblockcnt--;
    }
    //后面的为空则合并
    if((header->next != NULL)&&(header->next->type==BLOCK_FREE))
    {
        header->size += header->next->size;
        if(header->next->next!= NULL)
        {
            header->next->next->prev = header;
            header->next = header->next->next;
        }
        else
        {
            header->next = NULL;
        }
        memblockcnt--;
    }
}
/*****************************************************************************************
                                内存辅助分析--用于调试
*****************************************************************************************/
//总空间大小 若 AllSize == FreeSize + UsedSize 则正常,否则可能内存泄露、访问越界了
int BspMemAllSize(void)
{
    return HEAP_ALL_SIZE;
}
//空闲空间的大小
int BspMemFreeSize(void)
{
    int allsize = 0;
    heap_header *header = NULL;
    header = list_head;
    while(header != NULL)
    {
        if (header->type == BLOCK_FREE)
        {
            allsize += header->size;
        }
        header = header->next;
    }
    return allsize;
}
//使用的的空间大小
int BspMemUsedSize(void)
{
    int allsize = 0;
    heap_header *header = NULL;

    header = list_head;
    while(header != NULL)
    {
        if (header->type == BLOCK_USED)
        {
            allsize += header->size;
        }
        header = header->next;
    }
    return allsize;
}
//已经使用的了块数目
int BspMemUsedBlock(void)
{
    return memblockcnt;
}
//显示内存分配情况
void BspMemDisp(void)
{
    int i = 0;
    int allsize = 0;
    heap_header *header = NULL;
    //遍历
    header = list_head;
    while(header != NULL)
    {
        DBG_S_U32("\nMEM num = :",i);
        if (header->type == BLOCK_FREE)
        {
            DBG_S(" type = free");
        }else
        {
            DBG_S(" type = used");
        }
        DBG_S_U32(" size=",header->size);
        DBG_S_U32(" prev = :",(int)(header->prev) - (int)mem);
        DBG_S_U32(" this = :",(int)header - (int)mem);
        DBG_S_U32(" next = :",(int)(header->next) - (int)mem);
        DBG_S_U32(" this addr = :",(int)header);
        allsize += header->size;
        i++;
        header = header->next;
    }
    DBG_S_U32("\nall  size == ",allsize);
    DBG_S_U32("\nfree size == ",BspMemFreeSize());
    DBG_S_U32("\nUsed size == ",BspMemUsedSize());
    DBG_S("\n");
}
/*****************************************************************************************
                                测试函数
*****************************************************************************************/
void BspMemTest_(void)
{
    char *pc0;
    char *pc1;
    char *pc2;
    char *pc3;
    char *pc4;
    BspMemDisp();

    pc0 = BspMemMalloc(8);
    MathMemSet(pc0,0x11,8);

    pc1 = BspMemMalloc(8);
    MathMemSet(pc1,0x22,8);

    pc2 = BspMemMalloc(8);
    MathMemSet(pc2,0x33,8);

    pc3 = BspMemMalloc(4);
    MathMemSet(pc3,0x44,5);

    pc4 = BspMemMalloc(4);
    MathMemSet(pc4,0x55,4);
    BspMemDisp();

    BspMemFree(pc2);
    BspMemDisp();

    BspMemFree(pc0);
    BspMemDisp();

    BspMemFree(pc1);
    BspMemDisp();

    BspMemFree(pc3);
    BspMemDisp();

    BspMemFree(pc4);
    BspMemDisp();
}
int main(void)
{
    BspMemInit();
    BspMemDisp();
    BspMemTest_();
    BspMemTest_();
}