重复造轮子系列--内存池(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和主题,开发者就可以很方便 ...
随机推荐
- 如何在Linux中显示和设置主机名
原文链接 随着连接到网络的计算机数量越来越多,每一台计算机都需要有一个属性来区别于其它计算机.和现实世界中的人一样,计算机也有一个叫做hostname(主机名)的属性. 什么是hostname 从它的 ...
- 阿里数据库连接池druid
官方wiki: https://github.com/alibaba/druid/wiki 实用方法介绍的想当详细,包含监控.扩展.大力推荐!
- JSPatch库, 一个Apple官方支持的实现在线更新iOS应用的库
简介 项目主页: https://github.com/bang590/JSPatch 示例下载: https://github.com/ios122/ios122 JSPatch 可以让你用 Jav ...
- ReactiveObjC框架的简单介绍
最近在一直在学习RAC框架的Object-C版本ReactiveObjC(Swift版本为ReactiveSwift),这篇文章简单展示一下学习的成果!!!如果有什么地方理解错误,欢迎大家指正!!!互 ...
- Python 创建项目、应用
1.创建项目 django-admin startproject TestPython 2.创建应用 python3 manage.py startapp books 3.目录讲解 ├── TestP ...
- sqlite的sql常用语句(笔记)
1.复制一张表并重命名 比如已经创建好一个表 表名为"28165" 复制这个表. CREATE TABLE [33150] AS SELECT * FROM [28165] 2.根 ...
- python实现简单关联规则Apriori算法
from itertools import combinations from copy import deepcopy # 导入数据,并剔除支持度计数小于min_support的1项集 def lo ...
- scrapy--BeautifulSoup
BeautifulSoup官方文档:https://beautifulsoup.readthedocs.io/zh_CN/latest/#id8 太繁琐的,精简了一些自己用的到的. 1.index.h ...
- Aizu:2200-Mr. Rito Post Office
快递 Time limit 8000 ms Memory limit 131072 kB Problem Description 你是某个岛国(ACM-ICPC Japan)上的一个苦逼程序员,你有一 ...
- 常用 Git 命令清单【转--阮一峰】
常用 Git 命令清单 感谢作者 --> 原文链接 我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图6个命令,就可以了.但是熟练使用,恐怕要记住60-100个命令. 下 ...