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

三、运行结果

四、总结

希望能帮助到你。

相关推荐
起个网名真难~8 小时前
STM32F103_Bootloader_从零到UART升级成功_博客原稿
stm32·单片机·嵌入式硬件
二本咕咕-机械转码8 小时前
FreeRTOS深入解析(一)_链表与并发保护——哨兵循环链表、排序键游标、临界区与关调度
单片机·算法·链表
Zwawa10 小时前
串口命令如何从字符串长成协议:帧头、长度、校验和与状态机
c语言·单片机·嵌入式
小李不想当小白10 小时前
BKP备份寄存器与RTC实时时钟(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
铅笔小新z15 小时前
【stm32】WWDG(窗口看门狗)
stm32·单片机·嵌入式硬件
comyccccc16 小时前
平衡车底板设计:精准布局与高效布线学习笔记
单片机·嵌入式硬件
芯片人00717 小时前
GEK100系列芯片进入上市公司上海移远通信供应链
人工智能·单片机·嵌入式硬件·物联网·芯片
fly_sunnn18 小时前
ADC模数转换器
单片机·嵌入式硬件
我叫洋洋18 小时前
I2C 为什么必须用开漏输出?从推挽短路、线与,到上拉电阻取值
单片机·嵌入式硬件
无敌贵点大王19 小时前
从寄存器层面重学STM32(5)——串口USART理论部分
stm32·单片机·嵌入式硬件