C内存利用率最高的分配算法

个人原创,请勿抄袭。

转载请注明出处,谢谢!

个人邮箱 737355415@qq.com

------------------------------------------------------华丽的分割线-------------------------------------------------------- 
 

目录

1、整体构思:

  1.1 核心思想:

  1.2 图解:

2、mem.h

3、mem.cpp



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;
}

 

欢迎各路大神指点!


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值