内存池设计实现

1.设计原理

1.内存池实际就是预先分配不同大小的内存块, 然如果需要调用的时候, 直接把这个块的指针返回.

图中, 就是内存池划分.

2.通过一个链表, 将这些分配的内存块串联起来, 每一块最头部都记录这这个块的信息

3.分配的时候, 会遍历一遍链表, 找到is_used未被置1, pool_size大于或等于分配的大小的内存块(并且这个pool_size必定是内存池最小的那块), 如果找到, 则is_used被置1. 同时返回那个内存块的数据存储的首位置addr + sizeof(pool_t);.

4. 释放则是遍历每个内存块, 比较内存块加上一个pool_t的大小(if (pt + sizeof(pool_t) == p)), 是否和释放的指针相等

2.源码

2.1 头文件

#ifndef POOL_H
#define POOL_H
typedef struct pool{unsigned int pool_size;unsigned char is_used;struct pool *next;
}pool_t;
int init_pool(int arg_num, ...);
void* pool_malloc(unsigned int size);
unsigned char pool_free(void* p);#endif

2.2 C文件

#include "pool.h"
#include <stdarg.h>
#include <stdlib.h>
#include "./UART/uart.h"/*我们要进入启动文件, 调整一下堆区大小*/static pool_t pool_head = {0};int init_pool(int arg_num, ...)
{unsigned char i, j;unsigned int pool_size, pool_num;pool_t *new_pool, * p;p = &pool_head;va_list ap;va_start(ap, arg_num);for (i = 0; i < arg_num / 2; i++){pool_size = va_arg(ap, int);pool_num = va_arg(ap, int);for (j = 0; j < pool_num; j++){new_pool = (pool_t*)malloc(pool_size + sizeof(pool_t));if (new_pool == NULL){return 0;}new_pool->next = p->next;p->next = new_pool;new_pool->is_used = 0;new_pool->pool_size = pool_size;p = &pool_head;}}va_end(ap);return 1;
}void* pool_malloc(unsigned int size)
{pool_t* p = pool_head.next;pool_t* addr = &pool_head, *temp;while (p) {if (p->is_used == 0 && p->pool_size >= size){temp = p;if (addr == &pool_head){addr = temp;}else {if (addr->pool_size > temp->pool_size) {addr = temp;}}}p = p->next;}if (addr == &pool_head){printf("malloc failed\r\n");return 0;}addr->is_used = 1;return addr + sizeof(pool_t);
}unsigned char pool_free(void* p)
{unsigned char free_succes = 0;pool_t* pt = pool_head.next;while (pt){if (pt + sizeof(pool_t) == p) {free_succes = 1;break;}pt = pt->next;}pt->is_used = 0;return free_succes;
}

2.3 函数介绍

内存池初始化: 

int init_pool(int arg_num, ...);

 初始时一个不定长参数函数, 初始化的时候注意, init_pool(6, 200, 2, 300, 2, 400, 2);第一个参数是后面不定长参数的个数, 第二个参数是分配一个200字节大小的块, 第三个参数是分配200字节块的个数, 依次类推, 但是也要注意不用分配太大,.

注意: 这些都是没在实际项目中使用的, 还没接受过项目的考验, 但是理论上来讲, 如果是裸机代码从运行来看可以直接拿来用, 如果跑RTOS, 我还不能保证, 可能释放和分配要加互斥锁, 防止访问上造成冲突, 或者直接挂起任务调度, 或者进入临界区.如果有兄弟拿到项目, 发现问题,请评论下,我进行修改. 

2.4 测试

void main()
{int*p,*p1, *p2, *p3, *p4, *p5, *p6, *p7;init_pool(6, 200, 2, 300, 2, 400, 2);printf("sizeof(pool_t) = %d", sizeof(pool_t));p = (int*)pool_malloc(100);p1 = (int*)pool_malloc(100);p2 = (int*)pool_malloc(100);p3 = (int*)pool_malloc(100);p4 = (int*)pool_malloc(100);*p4 = 555;p5 = (int*)pool_malloc(100);p6 = (int*)pool_malloc(100);pool_free(p5);p7 = (int*)pool_malloc(100);while (1);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/130575.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

相机存储卡被格式化了怎么恢复?数据恢复办法分享!

随着时代的发展&#xff0c;相机被越来越多的用户所使用&#xff0c;这也意味着更多的用户面临着相机数据丢失的问题&#xff0c;很多用户在使用相机的过程中&#xff0c;都出现过不小心格式化相机存储卡的情况&#xff0c;里面的数据也将一并消失&#xff0c;相机存储卡被格式…

[iOS开发]iOS中TabBar中间按钮凸起的实现

在日常使用app的过程中&#xff0c;经常能看到人家实现了底部分栏控制器的中间按钮凸起的效果&#xff0c;那么这是怎么实现的呢&#xff1f; 效果演示&#xff1a; 实现原理&#xff1a; 创建按钮 创建一个UITabBar的子类&#xff0c;重写它的layoutSubviews方法&#xff1…

Global-aware siamese network for change detection on remote sensing images

遥感图像中的变化检测是以有效的方式识别观测变化的最重要的技术选择之一。CD具有广泛的应用&#xff0c;如土地利用调查、城市规划、环境监测和灾害测绘。然而&#xff0c;频繁出现的类不平衡问题给变化检测应用带来了巨大的挑战。为了解决这个问题&#xff0c;我们开发了一种…

数字化时代,数据仓库是什么?有什么用?

在激烈的市场竞争和全新的数字经济共同作用下&#xff0c;数字化转型成为了大多数企业的共识&#xff0c;也是获取数字经济的最佳方式。在整个数据价值生产链路中&#xff0c;数据仓库的主要作用就是中心化分发&#xff0c;将原始数据与数据价值挖掘活动隔离。 所有的原始数据…

基于 LangChain 构建 LLM 应用程序设计与实践

▼最近直播超级多&#xff0c;预约保你有收获 近期直播&#xff1a;《基 LangChain大模型架构案例实践》 —1— LangChain 是什么&#xff1f; LangChain 和 Semantic Kernel 是当前比较受欢迎的两款 LLM 应用开发框架。 LangChain 作为一个大语言模型应用开发框架&#xff0c;…

SpringBoot 将 jar 包和 lib 依赖分离,dockerfile 构建镜像

前言 Spring Boot 是一个非常流行的 Java 开发框架&#xff0c;它提供了很多便利的功能&#xff0c;例如自动配置、快速开发等等。 在使用 Spring Boot 进行开发时&#xff0c;我们通常会使用 Maven 或 Gradle 进行项目构建。 本文将为您介绍如何使用 Maven 将 Spring Boot …

如何从站长的角度选择高防CDN以节省成本

在当今的数字化世界中&#xff0c;网站站长需要面对越来越复杂的网络安全威胁&#xff0c;如DDoS攻击、恶意爬虫和恶意请求等。为了保护网站的可用性和数据安全&#xff0c;站长通常会寻求使用高防CDN&#xff08;内容分发网络&#xff09;。然而&#xff0c;如何在选择高防CDN…

基于Jaccard相似度的推荐算法---示例

目录 数据展示推荐算法的分类基于相似度基于流行度/上下文/社交网络 Jaccard相似度分析数据的特点可以考虑的方法计算方法优缺点计算用户之间的Jaccard相似度获取与给定最相似的10个用户对1713353的用户推荐10本书 数据展示 import pandas as pd import numpy as np# 读取CSV文…

面试梳理-Redis01

目录 开场白-追命3连 使用场景 01缓存穿透场景与方案 02布隆过滤器 03缓存击穿场景与方案 04缓存雪崩场景与方案 开场白-追命3连 看你项目中有说用到Redis&#xff0c;都是哪些场景使用了Redis呢&#xff1f; 如果发生了缓存穿透、击穿、雪崩如何应对呢&#xff1f;缓存…

【JVM】双亲委派机制、打破双亲委派机制

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaEE 操作系统 Redis 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 JVM 一、双亲委派机制1.1 双亲委派的作用1.…

【实战Flask API项目指南】之二 Flask基础知识

实战Flask API项目指南之 Flask基础知识 本系列文章将带你深入探索实战Flask API项目指南&#xff0c;通过跟随小菜的学习之旅&#xff0c;你将逐步掌握Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧&#xff01; 前言 当小菜踏入Flask后端开发的世界&…

node插件express(路由)的插件使用(二)——body-parser和ejs插件的基本使用

文章目录 前言一、express使用中间件body-parser获取请全体的数据1. 代码2. 效果 二、express使用ejs&#xff08;了解即可&#xff09;1.安装2.作用3.基本使用&#xff08;1&#xff09;代码&#xff08;2&#xff09;代码分析和效果 4.列表渲染&#xff08;1&#xff09;代码…

git更改远程仓库地址

1、输入命令【git remote -v】查看当前git远程仓库地址 2、输入命令【git remote set-url origin 新地址】替换成新地址 3、输入命令【git remote -v 】查看是否更新成功

Java 集合基础面试题(高频)

Java集合从分类上看&#xff0c;有 collection 和 map 两种&#xff0c;前者是存储对象的集合类&#xff0c;后者存储的是键值对&#xff08;key-value&#xff09; Collection Set 主要功能是保证存储的集合不会重复&#xff0c;至于集体是有序还是无序的&#xff0c;需要看…

MySQL 表的增删查改(CRUD)

MySQL 表的增删查改(CRUD) 文章目录 MySQL 表的增删查改(CRUD)1. 新增(Create)2. 查询(Retrieve)2.1 全列查询2.2 指定列查询2.3 查询字段为表达式2.4 别名2.5 去重&#xff1a;DISTINCT2.6 排序&#xff1a;ORDER BY2.7 条件查询2.8 分页查询: LIMIT 3. 修改(Update)4. 删除(D…

CodeWhisperer 的使用心得

文章作者&#xff1a;小SS 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术&#xff0c;观点&#xff0c;和项目&#xff0c;并将中国优秀开发者或技术推荐给全球云社…

王道p18 6.从有序顺序表中删除所有其值重复的元素,使表中所有元素的值均不同(c语言代码实现)

视频讲解在这里&#xff1a;&#x1f447; 顺序表p18 第6题wd数据结构课后代码题&#xff08;c语言代码实现&#xff09;_哔哩哔哩_bilibili 本题代码如下 void deleterepeat(struct sqlist* L) {if (L->length 0)printf("表空");int i 0;int k 0;for (i 1…

Android MVI架构的深入解析与对比

什么是MVI&#xff1f; M&#xff1a;model&#xff0c;此处的model并不是传统的数据模块&#xff0c;它是指用来存储视图状态UI State的一个模块 。比如请求数据时的loading、请求失败的提示页面等UI层面的变化状态。 V&#xff1a;view&#xff0c;视图模块 I&#xff1a;…

Mac终端学习

命令1&#xff1a;ifconfig 作用&#xff1a;列出本机所有的网络设备以及其上面的配置&#xff0c;主要指的是ip地址和mac地址 其他用法&#xff1a;sudo ifconfig en4 add 10.10.10.12 netmask 255.255.255.0 作用&#xff1a;给en4加入别的网段 其他用法&#xff1a;sudo i…

Visual Studio Code 常用快捷键大全

Visual Studio Code 常用快捷键大全 快捷键是编码过程中经常使用&#xff0c;且能够极大提升效率的部分&#xff0c;这里给大家介绍一些VS Code中非常有用的快捷键。 打开和关闭侧边栏 Mac — Command B Windows — Ctrl B Ubuntu — Ctrl B 选择单词 Mac — Command D …