• 周六. 4月 20th, 2024

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

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

admin

11月 28, 2021

在同事的帮助下,第一次尝试了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); }

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注