• 一个极其简单(陋)的内存分配器


    在同事的帮助下,第一次尝试了STM32程序的编写. 当然仅仅是C语言的部分, 并没有涉及到电子/硬件的操作. 相关操作还是同事实现的.

    当时使用了STM32 自带的 malloc, 后来发现程序运行久了会导致卡死. 其原因至今没有查清楚, 一来是因为能力不够,二是因为时间不足.

    最终是写了一个超级简陋的内存分配器, 当然了,肯定是不能用在多线程了. 而且分配次数还是有限的. 也请不要吐槽诸如使用了冒泡排序等.

    本文仅是简单地记录一下.

    头文件

    #ifndef __MY_MEM_H
    #define __MY_MEM_H
    
    #include <stdint.h>
    
    //一共可以申请的内存字节数
    #define MAMORY_SIZE 0x800
    
    //最多可以申请的次数
    #define MAX_MALLOC_CNT 10
    
    void Assert(int a);
    void InitMyMemory(void);
    void* Malloc(uint32_t size);
    void Free(void*);
    
    #endif
    

    代码

    #include "MyMem.h"
    
    //#ifndef Assert
    //#define Assert(a)                
    //    do{                                        
    //        while(!(a)){                
    //        }                                        
    //    }while(0)
    //#endif
    
    
    
        
    #ifndef NULL
    #define NULL 0
    #endif
        
    typedef struct
    {
        uint8_t * ptr;
    //    uint32_t size;
        uint8_t * end;
    }MyMallocInfo;
    
    typedef struct
    {
        uint8_t MEMORY[MAMORY_SIZE];
        MyMallocInfo Info[MAX_MALLOC_CNT];
        uint32_t count;
    }MyMemory;
    
    static MyMemory mem;
    //断言
    void Assert(int a){ int x=0; while(!a){ x++; } }
    //根据申请的内存地址
    //对MallocInfo进行排序
    void SortMallocInfo(){ uint32_t i,j; MyMallocInfo *ii; MyMallocInfo *ij; MyMallocInfo temp; for(i=0;i<mem.count;++i){ ii = &mem.Info[i]; for(j=i+1;j<mem.count;++j){ ij = &mem.Info[j]; if(ii->ptr > ij->ptr){ temp = *ii; *ii = *ij; *ij = temp; } } } } void InitMyMemory(){ mem.count = 0; } uint8_t * FindMemory(uint32_t size) {    // [start, end) uint8_t * start = mem.MEMORY; uint8_t * end = mem.MEMORY + MAMORY_SIZE;// not include
    uint32_t i; MyMallocInfo info; Assert(size > 0); for(i=0;i<mem.count;++i){ info = mem.Info[i];
         // 在 info间寻找没被分配的内存区域
         // 如果有没被分配的区域并且此区域字节大于申请的字节的话
    // 那就返回此区域给外部
    if(start < info.ptr){ if(info.ptr - start >= size){ return start; } } //否则 就查询下一个区域 start = info.end; }
      //最后一个memInfo后还有足够的空间(或者根本就没有memInfo,即mem.count = 0)
    if(end - start >= size){ return start; } return NULL; } //申请内存 void* Malloc(uint32_t size){ uint8_t * ptr; SortMallocInfo();
       //超过申请次数了, 返回NULL
    if(mem.count >= MAX_MALLOC_CNT){ return NULL; } ptr = FindMemory(size); if(ptr){ mem.Info[mem.count].ptr = ptr; mem.Info[mem.count].end = ptr + size; mem.count++; return ptr; } return NULL; }

    //释放内存
    void Free(void* ptr){ int32_t i; int32_t idx = -1;
      //找出对应的 memInfo 索引
    for(i=0;i<mem.count;++i){ if(mem.Info[i].ptr == ptr){ idx = i; break; } }
    //没有找到证明外部指针被修改了,直接让程序 crash更好 Assert(idx
    >= 0);
       //删除对应的 memInfo, 让后面的memInfo前置
    for(i=idx+1;i<mem.count;++i){ mem.Info[i-1] = mem.Info[i]; } mem.count--; //Assert(mem.count >= 0 && mem.count <= MAX_MALLOC_CNT); }
  • 相关阅读:
    前台 图片上传 上传预览 调用上传服务(多张图片展示)
    正则表达式验证,只能输入数字
    点击文本框搜索,出现在下拉列表中
    keycode 锁键盘按键(只能输入数字)
    Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
    map 理解
    mybatis 关联关系查询 java
    mybatis 批量插入值的sql
    EJB
    JPA概要
  • 原文地址:https://www.cnblogs.com/godzza/p/15062950.html
Copyright © 2020-2023  润新知