单片机实现内存管理的C语言实现

news/2024/9/21 3:27:58/

在嵌入式系统(如单片机)中,内存资源非常有限,因此需要高效的内存管理机制。在这种情况下,可能无法使用标准的动态内存管理函数(如 mallocfree)。因此,通常需要设计一个自定义的内存管理模块来管理内存池。

以下是一个简单的内存管理系统的C语言实现,适合用于单片机等嵌入式环境。该实现模拟了一个基本的内存池,并提供了分配和释放内存块的功能。

内存管理方案:

我们可以使用固定大小的内存块分配方案,每次分配固定大小的内存块,这种方案简单且适合内存较小的嵌入式系统。我们维护一个内存池并通过链表管理空闲的内存块。

内存管理代码实现:
#include <stdio.h>
#include <stdint.h>// 定义内存池参数
#define MEMORY_POOL_SIZE 1024  // 定义内存池大小为1024字节
#define BLOCK_SIZE 32          // 每个内存块的大小为32字节// 内存块结构体,用于链表管理空闲块
typedef struct MemoryBlock {struct MemoryBlock* next;  // 指向下一个空闲内存块
} MemoryBlock;// 内存池管理结构体
typedef struct {uint8_t memoryPool[MEMORY_POOL_SIZE]; // 实际的内存池MemoryBlock* freeList;                // 空闲内存块链表
} MemoryManager;MemoryManager memoryManager;// 初始化内存池,将所有内存块添加到空闲列表
void memoryManagerInit() {memoryManager.freeList = (MemoryBlock*)memoryManager.memoryPool; // 初始化空闲链表头MemoryBlock* currentBlock = memoryManager.freeList;// 将内存池划分为多个固定大小的内存块,并将它们链接成链表for (int i = 0; i < MEMORY_POOL_SIZE / BLOCK_SIZE - 1; i++) {currentBlock->next = (MemoryBlock*)((uint8_t*)currentBlock + BLOCK_SIZE); // 指向下一个内存块currentBlock = currentBlock->next;}currentBlock->next = NULL; // 最后一块的next指针置为NULL
}// 分配内存块
void* memoryAllocate() {if (memoryManager.freeList == NULL) {// 没有空闲块可用,返回NULLreturn NULL;}// 从空闲列表中取出一个内存块MemoryBlock* allocatedBlock = memoryManager.freeList;memoryManager.freeList = allocatedBlock->next;  // 将空闲列表的头指针指向下一个块return (void*)allocatedBlock;  // 返回分配的内存块
}// 释放内存块
void memoryFree(void* ptr) {if (ptr == NULL) {return;}// 将释放的内存块添加回空闲列表MemoryBlock* blockToFree = (MemoryBlock*)ptr;blockToFree->next = memoryManager.freeList; // 将该块指向当前空闲块的头memoryManager.freeList = blockToFree;       // 更新空闲块链表头为释放的块
}// 打印内存池的状态
void printMemoryStatus() {int freeBlocks = 0;MemoryBlock* currentBlock = memoryManager.freeList;while (currentBlock != NULL) {freeBlocks++;currentBlock = currentBlock->next;}printf("当前空闲内存块数量: %d\n", freeBlocks);
}int main() {// 初始化内存管理器memoryManagerInit();printMemoryStatus();// 分配几个内存块void* ptr1 = memoryAllocate();void* ptr2 = memoryAllocate();printMemoryStatus();// 释放一个内存块memoryFree(ptr1);printMemoryStatus();// 继续分配void* ptr3 = memoryAllocate();printMemoryStatus();// 释放所有内存块memoryFree(ptr2);memoryFree(ptr3);printMemoryStatus();return 0;
}

代码说明:

  1. 内存池结构memoryManager 包含一个静态的内存池数组 memoryPool,用于实际存储内存数据。此外,freeList 是一个指向空闲内存块的链表头。

  2. 内存池初始化:在 memoryManagerInit 函数中,将整个内存池划分为固定大小的内存块,并将这些块链接成一个链表。

  3. 内存分配 (memoryAllocate):每次分配内存时,从空闲链表中取出一个块,并将链表头指针指向下一个空闲块。

  4. 内存释放 (memoryFree):释放时,将内存块重新添加到空闲链表的头部。

  5. 内存状态打印 (printMemoryStatus):可以调用该函数查看当前剩余的空闲内存块数量。

优点:

  • 简单易用:通过固定块大小来简化内存管理,减少碎片化。
  • 高效:适合嵌入式系统或资源受限的单片机环境,因为避免了复杂的堆管理算法。

缺点:

  • 固定块大小:如果分配的内存请求大小不合适,可能会浪费内存。
  • 内存池大小固定:不能动态扩展或缩减内存池大小。

这个内存管理系统适合用于小型嵌入式系统,帮助开发者在有限的内存资源中实现动态内存分配和释放。


http://www.ppmy.cn/news/1528210.html

相关文章

【java面试每日五题之基础篇一】(仅个人理解)

1. 怎么理解面向对象编程&#xff08;Object Oriented Programming&#xff0c;OOP&#xff09; 面向对象编程是一种编程范式&#xff0c;核心思想是将真实世界中的事物都抽象为对象&#xff0c;通过与代码中的对象进行交互从而实现各种需求&#xff0c;对于OOP中关键概念的理解…

基于python flask的高血压疾病预测分析与可视化系统的设计与实现,使用随机森林、决策树、逻辑回归、xgboost等机器学习库预测

研究背景 随着现代社会的快速发展&#xff0c;生活方式的改变和人口老龄化的加剧&#xff0c;心血管疾病&#xff0c;尤其是高血压&#xff0c;已成为全球范围内的重大公共健康问题。高血压是一种常见的慢性疾病&#xff0c;其主要特征是动脉血压持续升高。长期不控制的高血压…

【云原生监控】Prometheus监控系统

Prometheus监控系统 文章目录 Prometheus监控系统资源列表基础环境一、部署Prometheus服务1.1、解压1.2、配置systemctl启动1.3、监听端口1.4、访问Prometheus仪表盘 二、部署Node-Exporter2.1、解压2.2、配置systemctl启动2.3、监听端口2.4、访问node-exporter仪表盘 三、配置…

Python | python中的特殊方法__str__和__repr__

__str__和__repr__ 无方法有方法__str____repr__同时存在 __str__和__repr__都是更改print的输出形式 无方法 无特殊方法 class Person:def __init__(self,name,age):self.name nameself.age ageprint(Person(aa, 34))<main.Person object at 0x000002231EF78B38> …

计算机毕业设计 大学志愿填报系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

Linux 防火墙:Firewalld 常用命令行操作命令

firewalld命令行操作管理 按增删改查分类&#xff0c;前面加上 firewall-cmd &#xff1a; ### 查询操作--get-default-zone 查看当前默认区域 --get-zones 查看所有可用的区域 --get-active-zones …

2024.9.13 Python与图像处理新国大EE5731课程大作业,SIFT 特征和描述符,单应性矩阵透视变换

1.SIFT特征点和描述符 import cv2 import numpy as np import matplotlib.pyplot as plt # read image img cv2.imread(im01.jpg,cv2.IMREAD_COLOR) gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) plt.imshow(gray,plt.cm.gray)提取图片&#xff0c;以灰度图像输出 #SIFT sift…

类型转换等 面试真题

题目1 请问哪个结果为NaN A. 123null B. 123‘1’ C. 123/0 D. 123undefined 在这四个表达式中&#xff0c;只有D. 123 undefined 的结果是 NaN&#xff0c;原因如下&#xff1a; A. 123 null 结果是&#xff1a;123原因&#xff1a;null 在数值运算中会被自动转换为 0&a…