重复造轮子系列--内存池(C语言)
这个代码是我上个公司工作项目的里面内存管理(基于伙伴算法)的一个简化又简化的版本。
因为没有内存边界检查;
因为没有内存使用统计;
因为没有考虑线程安全;
因为没有内存分配操作的具体文件位置信息;
因为没有考虑内存的浪费;
因为特别简单。。。所以也有一些用处,我定义了最小的内存为8字节,因此可以将任意内存大小散列到8的倍数之内,对于64位的通信系统来说,字节对齐是非常重要的;
mem_pool.h
#ifndef MEM_POOL_H_
#define MEM_POOL_H_ typedef struct MemBlock {
struct MemBlock* next;
int size;
void *ptr;
} MemBlock; typedef unsigned char byte; // 8 16 32 64 128 256 512 1024 2048 4096
// 1 2 4 8 16 32 64 128 256 512
// 0 1 2 3 4 5 6 7 8 9 #define MEM_POOL_MAX 10
#define MEM_BLOCK 8
#define MEM_BLOCK_BASE 8192
#define MEM_BLOCK_TYPE_NUM 10
#define MEM_BLOCK_FREE -1 int mem_pool_index(size_t size);
void mem_pool_init();
void mem_pool_free();
int mem_block_num(size_t size);
MemBlock* mem_block_head_get(size_t size);
void* mem_get(size_t size);
int mem_free(void **ptr); #define mem_ret(ptr) mem_free((void **)&ptr) ////////////////////////////////////////////////////////////////////////// typedef struct MemBlockDlist {
struct MemBlockDlist* prev;
struct MemBlockDlist* next;
int size;
void *ptr;
} MemBlockDlist; void mem_pool_dlist_init();
void mem_pool_dlist_free();
void* mem_realloc(size_t size);
void mem_release(void** ptr); #define mem_alloc(s) mem_realloc(s)
#define mem_relex(p) mem_release((void **)&p) #endif
mem_pool.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "mem_pool.h" static byte* g_pool_mem[MEM_POOL_MAX] = {};
static MemBlock* g_pool[MEM_POOL_MAX] = {};
const float log2 = log(2.0);
int mem_pool_index(size_t size) {
if (size > && size <= MEM_BLOCK) return ; size_t s = ;
size_t t = size;
size_t i; i = log((float)t)/log2;
17 s = s<<i;
return s == size ? i- : i-;
} MemBlock* mem_block_head(size_t index) {
if (index < || index >= MEM_POOL_MAX)
return NULL; return g_pool[index];
} MemBlock* mem_block_head_get(size_t size) {
if (size > MEM_BLOCK_BASE/ || size <= ) {
printf("size=%d too big to mem pool. using malloc plz\n", size);
return NULL;
}
return mem_block_head(mem_pool_index(size));
} int mem_block_num(size_t size) {
return MEM_BLOCK_BASE/size;// size > 0 is true
} static MemBlock* mem_block_alloc(byte* buf, int block_size, int block_num) {
MemBlock *head, *curr, *next;
int i; head = (MemBlock *)buf;
head->size = MEM_BLOCK_FREE;
head->ptr = (byte*)head + sizeof(MemBlock);
head->next = NULL; curr = head;
for (i=; i<block_num; i++) {
next = (MemBlock*)((byte*)curr + block_size);
next->size = MEM_BLOCK_FREE;
next->ptr = (byte*)next + sizeof(MemBlock);
curr->next = next;
next->next = NULL;
curr = next;
}
return head;
} void mem_pool_init() {
size_t l, i, s, n, b;
for (l=; l<MEM_BLOCK_TYPE_NUM; l++) {
i = 1 << l;
b = i * MEM_BLOCK;
s = b + sizeof(MemBlock);
n = mem_block_num(b); g_pool_mem[l] = (byte *)malloc(s * n);
if (NULL == g_pool_mem[l]) {
break;
}
g_pool[l] = mem_block_alloc(g_pool_mem[l], s, n);
}
return;
} void mem_pool_free() {
for (int i=; i<MEM_BLOCK_TYPE_NUM; i++) {
if (NULL != g_pool_mem[i]) {
free(g_pool_mem[i]);
g_pool_mem[i] = NULL;
g_pool[i] = NULL;
}
}
return;
} void* mem_get(size_t size) {
MemBlock* head = mem_block_head_get(size);
if (NULL == head) return NULL; do {
if (head->size == MEM_BLOCK_FREE) {
head->size = size;
return head->ptr;
} else {
head = head->next;
}
} while (head->next); return NULL;
} int mem_free(void **ptr) {
if (NULL == ptr || NULL == *ptr) return ; MemBlock *block = (MemBlock *)((byte*)(*ptr) - sizeof(MemBlock));
block->size = MEM_BLOCK_FREE; return ;
}
mem_pool_dlist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "mem_pool.h" static byte* g_pool_buff[MEM_POOL_MAX] = {};
static MemBlockDlist* g_pool_objects[MEM_POOL_MAX] = {};
static MemBlockDlist* g_pool_freelist[MEM_POOL_MAX] = {};
static MemBlockDlist* g_pool_cursor[MEM_POOL_MAX] = {}; MemBlockDlist* mem_block_dlist_head(size_t index) {
if (index < || index >= MEM_POOL_MAX)
return NULL; return g_pool_objects[index];
} void mem_pool_cursor_init() {
for(size_t i=; i<MEM_POOL_MAX; i++)
g_pool_cursor[i] = mem_block_dlist_head(i);
} static MemBlockDlist* mem_block_dlist_alloc(byte* buf, int bk_size, int bk_num){
MemBlockDlist *head, *curr, *next;
int i; head = (MemBlockDlist *)buf;
head->size = MEM_BLOCK_FREE;
head->ptr = (byte*)head + sizeof(MemBlockDlist);
head->prev = NULL;
head->next = NULL; curr = head;
for (i=; i<bk_num; i++) {
next = (MemBlockDlist*)((byte*)curr + bk_size);
next->size = MEM_BLOCK_FREE;
next->ptr = (byte*)next + sizeof(MemBlockDlist); curr->next = next;
next->prev = curr;
next->next = NULL; curr = next;
}
return head;
} void mem_pool_dlist_init() {
size_t l, i, s, n, b;
for (l=; l<MEM_BLOCK_TYPE_NUM; l++) {
i = 1 << l;
b = i * MEM_BLOCK;
s = b + sizeof(MemBlockDlist);
n = mem_block_num(b); g_pool_buff[l] = (byte *)malloc(s * n);
if (NULL == g_pool_buff[l]) {
break;
}
g_pool_objects[l] = mem_block_dlist_alloc(g_pool_buff[l], s, n);
} mem_pool_cursor_init();
} void mem_pool_dlist_free() {
for (int i=; i<MEM_BLOCK_TYPE_NUM; i++) {
if (NULL != g_pool_buff[i]) {
free(g_pool_buff[i]); g_pool_buff[i] = NULL;
g_pool_objects[i] = NULL;
g_pool_freelist[i] = NULL;
g_pool_cursor[i] = NULL;
}
}
} MemBlockDlist* mem_free_block_get(int index) {
if (index < || index >= MEM_POOL_MAX) return NULL; MemBlockDlist* tmp = g_pool_freelist[index];
if (!tmp) return NULL; g_pool_freelist[index] = tmp->next;
g_pool_freelist[index]->prev = NULL;
tmp->next = NULL; return tmp;
} void* mem_realloc(size_t size) {
int index = mem_pool_index(size);
if (index < || index >= MEM_POOL_MAX)
return NULL; MemBlockDlist* ptr = mem_free_block_get(index);
if (ptr) {
ptr->size = size;
return ptr->ptr;
} MemBlockDlist* cursor = g_pool_cursor[index];
if (NULL == cursor) {
printf("pool index=%d memory leak or queue is all used.\n", index);
return NULL;
} if (MEM_BLOCK_FREE == cursor->size) {
g_pool_cursor[index] = cursor->next;
cursor->size = size;
return cursor->ptr;
} return NULL;
} void mem_release(void** ptr) {
if (NULL == ptr || NULL == *ptr)
return; size_t len = sizeof(MemBlockDlist);
MemBlockDlist *block = (MemBlockDlist *)((byte*)(*ptr) - len); int index = mem_pool_index(block->size);
if (index < || index >= MEM_POOL_MAX)
return; memset((byte*)(*ptr), , block->size);
MemBlockDlist* top = g_pool_freelist[index]; g_pool_freelist[index] = block;
if (top) {
g_pool_freelist[index]->next = top;
} g_pool_freelist[index]->size = MEM_BLOCK_FREE;
}
重复造轮子系列--内存池(C语言)的更多相关文章
- 重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关
重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关 引言 重复造轮子系列是自己平时的一些总结.有的轮子依赖社区提供的轮子为基础,这里把使用过程的一些觉得有意思的做个分享.有些思路或者方法在 ...
- 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印
重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...
- 重复造轮子系列--字符串处理(C语言)
这些字符代码是以前写的,源于很久很久以前的一个VC++项目,在当时的部门编程比赛里因为用了项目代码的xsplit函数,万万没想到,那个做了几年的项目里面居然有坑..xsplit函数居然不能split连 ...
- 重复造轮子系列--dijkstra算法
前年一时脑热(理想很丰满,现实很骨感),写了这个最短路径优先的低效版本,且留着回忆吧. spf.h #ifndef SPF_H_ #define SPF_H_ typedef struct { int ...
- 避免重复造轮子的UI自动化测试框架开发
一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...
- 第27篇 重复造轮子---模拟IIS服务器
在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西 ...
- 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)
一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...
- 54 个官方 Spring Boot Starters 出炉!别再重复造轮子了…….
在之前的文章,栈长介绍了 Spring Boot Starters,不清楚的可以点击链接进去看下. 前段时间 Spring Boot 2.4.0 也发布了,本文栈长再详细总结下最新的 Spring B ...
- GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。
1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...
随机推荐
- 简单使用hibernate(idea中使用)
首先创建一个maven项目 创建成功后,进行创建数据库的表 CREATE TABLE BOOK( ID INT AUTO_INCREMENT PRIMARY KEY, NAME ), NUMBER i ...
- VMWare关闭beep声
在虚拟机文件夹下找到 .vmx 文件,在文件末尾添加 mks.noBeep = "TRUE" ,重启虚拟机即可.
- 【Java-Method】读《重构》有感_Java方法到底是传值调用还是传引用调用(传钥匙调用)
今天读<重构>P279, Separate Query from Modifier,将查询函数和修改函数分离. 问题的产生 突然想到 Java 的传对象作为参数的方法到底是 传引用调用,还 ...
- sudo 密码超时时间
Centos 没有默认超时时间,所以用一次sudo就需要输入密码. vi /etc/sudoers 添加下面的内容,2表示分钟数(看自己需求更改). Defaults timestamp_timeou ...
- virtual base classes
virtual base classes用来实现菱形继承解决多个重复subobject的问题 //: C09:VirtualBase.cpp // Shows a shared subobject v ...
- Swift小记一
1.输出地址 print(String(format: "%p", "temp")) 2.判断字符串是否为空串.是否为nil 为String添加一个分类 ext ...
- 使用泛型实现对int数组或者String数组进行排序
因为是使用的泛型,我们并不确定数据类型, 对于数据的比较就不能用平时的大于或者小于. 我们需要比较对象实现Comparable接口,该接口下的compareTo()方法可以用来比大小 定义Sort类: ...
- Linux系统崩溃,数据迁移
就在1小时前,处理了件如标题所述的麻烦事儿.吃完午饭,想对此作个总结,一来自己梳理下过程以便后面遇见类似的事可以 快速处理,二来同行的小伙伴们可以探讨下.故事是这样的,公司所在园区物业晚上断电8小时, ...
- 原生js关闭窗口
if (navigator.userAgent.indexOf("MSIE") > 0) { if (navigator.userAgent.indexOf("MS ...
- 【vlan-端口配置】
搭建好拓扑图如下: 分别配置两台终端的ip地址 创建vlan把e0/4/0接口加入到新的vlan中 连通性失败 . 同理在把e0/4/1加入到vlan视图中 连通性成功 : 搭建好拓扑图如下 进入e0 ...