C语言-简单实现单片机中的malloc示例

概述

在实际项目中,有些单片机资源紧缺,需要mallloc内存,库又没有自带malloc函数时,此时,就需要手动编写,在此做个笔录。(已在项目上使用),还可进入对齐管理机制。

直接上源码 ^_^

一、示例1:

1、mem_malloc.h文件

cpp 复制代码
#ifndef __MEM_MALLOC_H__
#define __MEM_MALLOC_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h>

void* mem_malloc(size_t size);
void mem_free(void* ptr);


#ifdef __cplusplus
}
#endif

#endif

2、mem_malloc.c文件

cpp 复制代码
#include "mem_malloc.h"
#include "stdint.h"


// 定义内存块结构
typedef struct MemoryBlock {
    size_t size;
    struct MemoryBlock* next;
} MemoryBlock;

// 定义内存池起始地址
#define MEMORY_POOL_SIZE 1024
static uint8_t memoryPool[MEMORY_POOL_SIZE];

// 全局指针,指向内存池起始位置
static MemoryBlock* memoryPoolPtr = NULL;

// 初始化内存池
void memoryPoolInit(void)
{
    memoryPoolPtr = (MemoryBlock*)memoryPool;
    memoryPoolPtr->size = MEMORY_POOL_SIZE - sizeof(MemoryBlock);
    memoryPoolPtr->next = NULL;
}

// 分配内存
void* mem_malloc(size_t size)
{
    //memoryPoolInit();

    if (size == 0)
        return NULL;

    MemoryBlock* currentBlock = memoryPoolPtr;
    //MemoryBlock* prevBlock = NULL;

    // 遍历内存池中的内存块,找到合适大小的内存块
    while (currentBlock != NULL) {
        if (currentBlock->size >= size + sizeof(MemoryBlock)) {
            // 如果当前内存块大于所需内存,分配内存
            if (currentBlock->size >= size + sizeof(MemoryBlock) + sizeof(size_t)) {
                MemoryBlock* newBlock = (MemoryBlock*)((uint8_t*)currentBlock + sizeof(MemoryBlock) + size);
                newBlock->size = currentBlock->size - sizeof(MemoryBlock) - size;
                newBlock->next = currentBlock->next;
                currentBlock->next = newBlock;
                currentBlock->size = size;
            }

            // 返回分配的内存块的地址
            return (uint8_t*)currentBlock + sizeof(MemoryBlock);
        }

        //prevBlock = currentBlock;
        currentBlock = currentBlock->next;
    }

    // 没有足够的内存块可供分配
    return NULL;
}

// 释放内存
void mem_free(void* ptr)
{
    if (ptr == NULL)
        return;

    MemoryBlock* block = (MemoryBlock*)((uint8_t*)ptr - sizeof(MemoryBlock));
    block->next = memoryPoolPtr;
    memoryPoolPtr = block;
}


// 示例代码
int main(void) 
{
    // 初始化内存池
    memoryPoolInit();

    // 分配内存
    int* intPtr = (int*)mem_malloc(sizeof(int));
    if (intPtr != NULL) {
        *intPtr = 42;
        free(intPtr);
    }

    return 0;
}

二、示例2:

cpp 复制代码
#include <stdio.h>



#define MEMORY_POOL_SIZE (1024 * 2)

unsigned char memoryBuff[MEMORY_POOL_SIZE];

typedef struct {
	unsigned char* start;
	size_t size;
} MemoryBlock;

static MemoryBlock memoryBlocks[MEMORY_POOL_SIZE] = { 0 };
static int numBlocks = 0;

// 从内存池中分配内存
void* mem_malloc(size_t size)
{
	// 寻找空闲块
	for (int i = 0; i < numBlocks; i++) {
		if (memoryBlocks[i].size == 0 && size <= MEMORY_POOL_SIZE) {
			// 找到合适大小的内存块,返回内存块地址
			memoryBlocks[i].start = memoryBuff;
			memoryBlocks[i].size = size;
			return memoryBlocks[i].start;
		}
	}

	// 分配新的块
	if (numBlocks < MEMORY_POOL_SIZE) {
		memoryBlocks[numBlocks].start = memoryBuff + numBlocks;
		memoryBlocks[numBlocks].size = size;
		numBlocks++;
		return memoryBlocks[numBlocks - 1].start;
	}

	// 分配失败
	return NULL;
}

void mem_free(void* ptr)
{
	// 查找要释放的块
	for (int i = 0; i < numBlocks; i++) {
		if (memoryBlocks[i].start == ptr) {
			memoryBlocks[i].size = 0;
			break;
		}
	}
}

int main(void)
{
	// 使用mem_malloc和mem_free进行内存管理
	unsigned char* ptr1 = (unsigned char*)mem_malloc(50);
	unsigned char* ptr2 = (unsigned char*)mem_malloc(100);

	if (ptr1 != NULL && ptr2 != NULL) {
		// 使用分配的内存
		for (int i = 0; i < 50; i++) {
			ptr1[i] = i;
		}

		for (int i = 0; i < 100; i++) {
			ptr2[i] = i + 50;
		}

		// 打印分配的内存
		printf("ptr1: ");
		for (int i = 0; i < 50; i++) {
			printf("%d ", ptr1[i]);
		}
		printf("\n");

		printf("ptr2: ");
		for (int i = 0; i < 100; i++) {
			printf("%d ", ptr2[i]);
		}
		printf("\n");
	}

	mem_free(ptr1);
	mem_free(ptr2);

	return 0;
}

三、运行结果

四、总结

希望能帮助到你。

相关推荐
创界工坊工作室10 小时前
22-基于STM32的汽车防盗系统设计
stm32·单片机·嵌入式硬件·proteus
雨田言炎12 小时前
STM32之RCC系统时钟控制(芯片的心脏控制器)
stm32·单片机·嵌入式硬件
李永奉12 小时前
日常使用的锂电池上,新、旧锂电池的差异分析
单片机·嵌入式硬件·物联网·智能手机·电脑
额额额对了12 小时前
IMX6ULL 杂项设备 LED 驱动
stm32·单片机·嵌入式硬件
长春的KAKA13 小时前
Proxmark3 Iceman分支CLI命令总表
嵌入式硬件
半杯咖啡半行码14 小时前
STM32开发之IIC通信详解:从协议基础到FM24CL04实战
stm32·单片机·嵌入式硬件
硅基手札15 小时前
【I2C 技术系列 05】I2C 多主仲裁与时钟同步
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
szxinmai主板定制专家15 小时前
面向虚拟电厂协调控制:RK3588+FPGA+AI边缘控制器设计思路与算力评估
人工智能·嵌入式硬件·fpga开发·机器人·jetson·zynq·振动采集
硅基手札15 小时前
【I2C 技术系列 01】I2C 电气特性与物理层
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
comyccccc15 小时前
TB6612电机驱动板原理图与PCB设计学习笔记
单片机·嵌入式硬件