这个代码是我上个公司工作项目的里面内存管理(基于伙伴算法)的一个简化又简化的版本。

因为没有内存边界检查;

因为没有内存使用统计;

因为没有考虑线程安全;

因为没有内存分配操作的具体文件位置信息;

因为没有考虑内存的浪费;

因为特别简单。。。所以也有一些用处,我定义了最小的内存为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语言)的更多相关文章

  1. 重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关

    重复造轮子系列——基于Ocelot实现类似支付宝接口模式的网关 引言 重复造轮子系列是自己平时的一些总结.有的轮子依赖社区提供的轮子为基础,这里把使用过程的一些觉得有意思的做个分享.有些思路或者方法在 ...

  2. 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印

    重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...

  3. 重复造轮子系列--字符串处理(C语言)

    这些字符代码是以前写的,源于很久很久以前的一个VC++项目,在当时的部门编程比赛里因为用了项目代码的xsplit函数,万万没想到,那个做了几年的项目里面居然有坑..xsplit函数居然不能split连 ...

  4. 重复造轮子系列--dijkstra算法

    前年一时脑热(理想很丰满,现实很骨感),写了这个最短路径优先的低效版本,且留着回忆吧. spf.h #ifndef SPF_H_ #define SPF_H_ typedef struct { int ...

  5. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

  6. 第27篇 重复造轮子---模拟IIS服务器

    在写程序的时候,重复造轮子是程序员的一个大忌,很多人对重复造轮子持有反对的态度,但是我觉得这个造轮子的过程,是对于现有的知识的一个深入的探索的过程,虽然我们不可能把轮子造的那么的完善,对于现在有的东西 ...

  7. 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)

    一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...

  8. 54 个官方 Spring Boot Starters 出炉!别再重复造轮子了…….

    在之前的文章,栈长介绍了 Spring Boot Starters,不清楚的可以点击链接进去看下. 前段时间 Spring Boot 2.4.0 也发布了,本文栈长再详细总结下最新的 Spring B ...

  9. GitHub Android 最火开源项目Top20 GitHub 上的开源项目不胜枚举,越来越多的开源项目正在迁移到GitHub平台上。基于不要重复造轮子的原则,了解当下比较流行的Android与iOS开源项目很是必要。利用这些项目,有时能够让你达到事半功倍的效果。

    1. ActionBarSherlock(推荐) ActionBarSherlock应该算得上是GitHub上最火的Android开源项目了,它是一个独立的库,通过一个API和主题,开发者就可以很方便 ...

随机推荐

  1. 斯坦福大学3D模型库-The Stanford 3D Scanning Repository

    这里总是让人感觉有差距的地方!!! http://graphics.stanford.edu/data/3Dscanrep/

  2. 第24章 SPI—读写串行FLASH—零死角玩转STM32-F429系列

    第24章     SPI—读写串行FLASH 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  3. 史上最简单的SpringCloud教程 | 第十一篇: docker部署spring cloud项目

    转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springcloud/2017/07/12/sc11-docker/ 本文出自方志朋的博客 一.docker简介 ...

  4. Android 最新学习资料收集

    收集这份资料的灵感来源于我的浏览器收藏夹快爆了,后来在github 上也看到了很优秀的开源库的收集资料,非常的好,但是太过于多,也不够新,所以决定自己来做一个.原始的markdowm文件已经放到git ...

  5. EAIntroView–高度可定制的iOS应用欢迎页通用解决方案

    简介 高度可定制的应用欢迎页通用解决方案,可高度定制,不要仅限于现有的demo. 项目主页: EAIntroView 最新示例: 点击下载 入门 安装 安装后,引入” EAIntroView.h”并设 ...

  6. socket传送二进制流的一些总结

    第一次实质性的接触socket通信方面的工作,所以遇到的问题还真不少,写篇博客记录一下,提升下记忆. 需求是通过私有协议进行二进制数据的传输,必须保证数据包不能被丢失,所以选择tcp的socket进行 ...

  7. django连接mysql数据库配置,出现no module named mysqldb报错

    作为一个菜鸟运维也是要有梦想的,万一学会了python走向人生巅峰了呢.好吧,都是瞎想,今天主要介绍下django配置,最近也开始摸索这个牛b框架了,当然大佬肯定不屑一顾,都是照顾照顾我们这些菜鸟初学 ...

  8. TP5 webuploader 单页面多实例上传图片 案例

    在使用 webuploader上传文件过程中,如果同一个页面存在多个上传区域,可以参考本示例代码. HTML 代码: <!DOCTYPE html> <html> <he ...

  9. ios 苹果内购订单验证 --- nodejs实现

    实现代码 function IosPlayVerify(data,orderid,cb) { itunesPost(data,function (error,responseData) { if (e ...

  10. 从0开始学习 Git

    1. 什么是Git? Git 是 Linux 发明者 Linus 开发的一款新时代的版本控制系统,那什么是版本控制系统呢?怎么理解?网上一大堆详细的介绍,但是大多枯燥乏味,对于新手也很难理解,这里我只 ...