个人原创,请勿抄袭。
转载请注明出处,谢谢!
个人邮箱 737355415@qq.com
------------------------------------------------------华丽的分割线--------------------------------------------------------
目录
1、整体构思:
1.1 核心思想:
每个任务块由链表节点和内存区域构成
1.2 图解:
2、mem.h
#ifndef _MEM_H_
#define _MEM_H_
//而这一部分就是告诉编译器,如果定义了__cplusplus(即如果是cpp文件,
//因为cpp文件默认定义了该宏),则采用C语言方式进行编译
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned int U32 ;
typedef signed int s32;
#pragma pack(4)
#define NULL 0
#define MEM_LEN_ALL 512
#define MEM_LEN_STRUCT sizeof(TS_MEM_NODE)
#define MEM_DATA_TYPE u8
//---------------------------------------------
// 内存块链表
//---------------------------------------------
typedef struct _TS_MEM_NODE_
{
u32 len : 31; // 当前内存块的长度
u32 status : 1 ; // 是否被使用
struct _TS_MEM_NODE_* plast; // 指向上个内存块的地址
struct _TS_MEM_NODE_* pnext; // 指向下个内存块的地址
}TS_MEM_NODE;
typedef enum _TS_MEM_STATUS_
{
USED, // 使用
FREE, // 空闲
}TS_MEM_STATUS;
void MEM_Init(void); // 内存初始化
TS_MEM_NODE* MEM_Head_Get(void);
void* MEM_Alloc(u32); // 内存分配
u32 MEM_Free(void* memnode);
#ifdef __cplusplus
}
#endif
#endif
3、mem.cpp
#include "mem.h"
#include <stdio.h>
MEM_DATA_TYPE MEM_ALLOCATED[MEM_LEN_ALL] = { 0x0 }; // 申请一块连续地址作为内存分配
TS_MEM_NODE * MEM_HEAD = NULL; // 内存链表索引头
TS_MEM_NODE * MEM_NODE = NULL; // 内存链表头节点
static void mem_cpy(void* buf, void* src, u8 len);
static void mem_set(void* buf, u8 i, u8 len);
static u8 mem_len(void* buf);
static u8 mem_cmp(void* buf, void* src);
void MEM_Init(void) // 内存初始化
{
// 头索引不许动
MEM_HEAD = (TS_MEM_NODE*)MEM_ALLOCATED; // 指向数组第一个位置
//MEM_NODE = (TS_MEM_NODE*)&MEM_ALLOCATED[MEM_LEN_STRUCT]; // 指向数组第12个位置
MEM_NODE = MEM_HEAD + 1;
MEM_HEAD->len = 0;
MEM_HEAD->status = USED;
MEM_HEAD->plast = MEM_NODE;
MEM_HEAD->pnext = MEM_NODE;
MEM_NODE->len = MEM_LEN_ALL - MEM_LEN_STRUCT - MEM_LEN_STRUCT;
MEM_NODE->status = FREE;
MEM_NODE->plast = MEM_HEAD;
MEM_NODE->pnext = MEM_HEAD;
}
void* MEM_Alloc(u32 memlen) // 内存分配
{
TS_MEM_NODE* mem_node = MEM_HEAD; // 这个的功能主要是 用链表 寻找可用的 块
TS_MEM_NODE* mem_new = NULL; // 新内存块的地址
TS_MEM_NODE* mem_free = NULL;
u8* mem8free = NULL;
u32 lenfree=0;
while (1)
{
while (mem_node->status == USED)
{
if (mem_node->pnext == MEM_HEAD) // 如果最后一个节点都被使用中
return NULL; // 没有申请空间了
mem_node = mem_node->pnext; //
}
// 能运行到这里,肯定是有空闲块存在
if (mem_node->len < memlen) // 如果该内存块长度不够
{
if (mem_node->pnext == MEM_HEAD) // 如果已经是最后一块了
return NULL; // 申请空间太大
mem_node = mem_node->pnext; // 继续找下一块
continue;
}
lenfree = mem_node->len; // 当前块空闲长度 以字节为单位
mem_new = mem_node; // 新节点
// 这里涉及到一个 字节对齐 4字节
if (memlen%4 != 0)
{
memlen = memlen + 4 - memlen%4;
}
mem8free = ((u8*)mem_new) + MEM_LEN_STRUCT + memlen; // 以字节单位移动节点
mem_free = (TS_MEM_NODE*)mem8free;
mem_free->pnext = mem_new->pnext;
mem_free->plast = mem_new;
mem_new->pnext->plast = mem_free;
mem_new->pnext = mem_free;
mem_new->len = memlen;
mem_new->status = USED;
mem_free->len = lenfree - memlen - MEM_LEN_STRUCT;
mem_free->status = FREE;
return (mem_new+1);
}
}
u32 MEM_Free(void* memnode)
{
TS_MEM_NODE* mem_node = MEM_HEAD; // 这个的功能主要是 用链表 寻找可用的 块
TS_MEM_NODE* mem_del = ((TS_MEM_NODE*)memnode) - 1;
while (mem_node != mem_del)
{
if (mem_node->pnext == MEM_HEAD)
return 1; // 不存在
mem_node = mem_node->pnext;
}
mem_node->status = FREE;
// free节点
if (mem_node->pnext != MEM_HEAD)
{
// 下个节点是否空闲
if (mem_node->pnext->status == FREE)
{
mem_node->len += (mem_node->pnext->len + MEM_LEN_STRUCT);
mem_node->status = FREE;
mem_node->pnext = mem_node->pnext->pnext;
mem_node->pnext->plast = mem_node;
}
}
// 上个节点是否空闲
if (mem_node->plast != MEM_HEAD)
{
if (mem_node->plast->status == FREE)
{
mem_node->plast->len += (mem_node->len + MEM_LEN_STRUCT);
mem_node->plast->pnext = mem_node->pnext;
mem_node->pnext->plast = mem_node->plast;
}
}
mem_del = NULL;
return 0; // 成功
}
TS_MEM_NODE* MEM_Head_Get()
{
return MEM_HEAD;
}
static void mem_cpy(void* buf, void* src, u8 len)
{
u8* pbuf = (u8*)buf;
u8* psrc = (u8*)src;
while (len--)
{
*pbuf++ = *psrc++;
}
}
static u8 mem_cmp(void* buf, void* src)
{
u8* pbuf = (u8*)buf;
u8* psrc = (u8*)src;
while (*pbuf != '\0')
{
if (*pbuf++ != *psrc++)
return 0;
}
return 1;
}
static void mem_set(void* buf, u8 i, u8 len)
{
u8* pbuf = (u8*)buf;
while (len--)
{
*pbuf++ = i;
}
}
static u8 mem_len(void* buf)
{
u8 len = 0;
u8* pbuf = (u8*)buf;
while (*pbuf++ != '\0')
{
len++;
}
return len;
}
欢迎各路大神指点!