论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
数据库
›
分布式数据库
›
单片机实现内存管理的C语言实现
单片机实现内存管理的C语言实现
雁过留声
金牌会员
|
2024-9-21 00:57:31
|
显示全部楼层
|
阅读模式
楼主
主题
972
|
帖子
972
|
积分
2916
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
在嵌入式体系(如单片机)中,内存资源非常有限,因此需要高效的内存管理机制。在这种情况下,可能无法使用标准的动态内存管理函数(如 malloc 和 free)。因此,通常需要设计一个自定义的内存管理模块来管理内存池。
以下是一个简单的内存管理体系的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) {
// 没有空闲块可用,返回NULL
return 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;
}
复制代码
代码阐明:
内存池布局
:memoryManager 包含一个静态的内存池数组 memoryPool,用于现实存储内存数据。此外,freeList 是一个指向空闲内存块的链表头。
内存池初始化
:在 memoryManagerInit 函数中,将整个内存池划分为固定巨细的内存块,并将这些块链接成一个链表。
内存分配 (memoryAllocate)
:每次分配内存时,从空闲链表中取出一个块,并将链表头指针指向下一个空闲块。
内存开释 (memoryFree)
:开释时,将内存块重新添加到空闲链表的头部。
内存状态打印 (printMemoryStatus)
:可以调用该函数查看当前剩余的空闲内存块数量。
长处:
简单易用
:通过固定块巨细来简化内存管理,淘汰碎片化。
高效
:得当嵌入式体系或资源受限的单片机情况,由于制止了复杂的堆管理算法。
缺点:
固定块巨细
:假如分配的内存请求巨细不合适,可能会浪费内存。
内存池巨细固定
:不能动态扩展或缩减内存池巨细。
这个内存管理体系得当用于小型嵌入式体系,帮助开辟者在有限的内存资源中实现动态内存分配和开释。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
雁过留声
金牌会员
这个人很懒什么都没写!
楼主热帖
XShell免费版的安装配置教程以及使用教 ...
阿里云体验有奖:如何将 PolarDB-X 与 ...
day02-代码实现01
【如何优化她】教你如何定位不合理的SQ ...
微服务大行其道的今天,Service Mesh是 ...
十年技术进阶路,让我明白了三件要事( ...
常用类-LocalDate、LocalTime、LocalDa ...
无需支付688苹果开发者账号,xcode13打 ...
鸿蒙3.0来了,这次,我真的想批评鸿蒙 ...
Elasticsearch 入门实战(5)--Java API ...
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
网络安全
DevOps与敏捷开发
程序人生
前端开发
SQL-Server
Mysql
云原生
快速回复
返回顶部
返回列表