内存池设计实现

编程入门 行业动态 更新时间:2024-10-20 09:20:04

<a href=https://www.elefans.com/category/jswz/34/1771154.html style=内存池设计实现"/>

内存池设计实现

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

更多推荐

内存池设计实现

本文发布于:2023-11-16 15:37:08,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1626823.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:内存

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!