这是我的工具库中最后一个内存分配相关工具,其主要用途是,在某一函数或一个作用域中需要
使用动态内存,出了这个作用域之后,马上就释放这些分配的内存.
其主要工作模式是,函数开始时分配一大块内存,由分配器管理,函数中需要使用的动态内存
全都由分配器从这块大的内存中分配出来,分配出来的内存无需free,函数返回之前销毁分配
器,由分配将开始分配的大块内存释放.
local_pool.h
#ifndef _LOCAL_POOL_H
#define _LOCAL_POOL_H
typedef local_pool *local_pool_t;
/*
* pool:外部传进来的大内存块首地址,当这个参数不为0时,
* 内存块的释放交由应用完成,当内存总的使用量大概
* 可以确定是,直接传递一个栈上分配的缓冲地址进来
* 也是可以的.如果这个参数为0将会创建一个大小为size
* 的缓冲区,并在local_pool_destroy时将这块缓冲区释放.
*
*/
local_pool_t local_pool_create(void *pool,int size);
void local_pool_destroy(local_pool_t*);
void *local_pool_alloc(local_pool_t,int);
void local_pool_dealloc(local_pool_t,void*);
#endif
local_pool.c
#include "../include/local_pool.h"
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
struct local_pool
{
unsigned int free_size;
int free_buf_in_destroy;
char *buf_ptr;
char *free_ptr;
};
local_pool_t local_pool_create(void *buf,unsigned int size)
{
local_pool_t lp = malloc(sizeof(*lp));
if(!lp)
return 0;
if(buf)
{
lp->buf_ptr = buf;
lp->free_buf_in_destroy = 1;
}
else
{
lp->buf_ptr = malloc(size);
if(!lp->buf_ptr)
{
free(lp);
return 0;
}
lp->free_buf_in_destroy = 0;
}
lp->free_ptr = lp->buf_ptr;
lp->free_size = size;
return lp;
}
void local_pool_destroy(local_pool_t *lp)
{
assert(lp);
assert(*lp);
if(!(*lp)->free_buf_in_destroy)
free((*lp)->buf_ptr);
*lp = 0;
}
extern unsigned int alignsize(unsigned int obj_size);
void *local_pool_alloc(local_pool_t lp,int size)
{
assert(lp);
unsigned int alloc_size;
if(size <= 0)
alloc_size = 1;
alloc_size = alignsize(alloc_size);
if(lp->free_size < alloc_size)
return 0;
void *ret = (void*)lp->free_ptr;
lp->free_size -= alloc_size;
lp->free_ptr += alloc_size;
return ret;
}
void local_pool_dealloc(local_pool_t lp,void *ptr)
{
//什么也不做
}
local_pool介绍完毕.现在工具库中可使用的内存分配器总共有4种,为了统一接口
方便应用在不知道具体分配器类型的情况下正确的使用分配器,下面介绍统一的分
配器接口抽象.
allocator.h
#ifndef _ALLOCATOR_H
#define _ALLOCATOR_H
//内存分配器接口类
struct allocator
{
void* (*Alloc)(struct allocator*,int);
void (*DeAlloc)(struct allocator*,void*);
void (*Destroy)(struct allocator**);
};
#ifndef IMPLEMEMT
#define IMPLEMEMT(SUPER_CLASS) struct SUPER_CLASS super_class
#endif
#ifndef ALLOC
#define ALLOC(ALLOCATOR,SIZE)\
({ void *__result;\
do \
if(ALLOCATOR)\
__result = ((struct allocator*)ALLOCATOR)->Alloc(ALLOCATOR,SIZE);\
else\
__result = malloc(SIZE);\
while(0);\
__result;})
#endif
#ifndef FREE
#define FREE(ALLOCATOR,PTR)\
({\
do \
if(ALLOCATOR)\
((struct allocator*)ALLOCATOR)->DeAlloc(ALLOCATOR,PTR);\
else\
free(PTR);\
while(0);\
})
#endif
#ifndef DESTROY
#define DESTROY(ALLOCATOR)\
((struct allocator*)(*ALLOCATOR))->Destroy(ALLOCATOR)
#endif
#endif
分配器接口的使用实例如下:
#include "../include/allocator.h"
struct fix_obj_pool
{
IMPLEMEMT(allocator);
};
struct first_fit_pool
{
IMPLEMEMT(allocator);
};
void* fix_alloc(struct allocator *al,int size)
{
struct fix_obj_pool *fix_al = (struct fix_obj_pool *)al;
printf("fix_alloc\n");
}
void fix_free(struct allocator *al,void *ptr)
{
printf("fix_free\n");
}
void destroy_fix_pool(struct allocator **al)
{
printf("destroy_fix_pool\n");
}
void* first_alloc(struct allocator *al,int size)
{
printf("first_alloc\n");
}
void first_free(struct allocator *al,void *ptr)
{
printf("first_free\n");
}
void destroy_first_fit(struct allocator **al)
{
printf("destroy_first_fit\n");
}
struct allocator* create_fix_pool()
{
struct fix_obj_pool *pool = malloc(sizeof(struct fix_obj_pool));
pool->super_class.Alloc = fix_alloc;
pool->super_class.DeAlloc = fix_free;
pool->super_class.Destroy = destroy_fix_pool;
return (struct allocator*)pool;
}
struct allocator* create_first_fit_pool()
{
struct first_fit_pool *pool = malloc(sizeof(struct first_fit_pool));
pool->super_class.Alloc = first_alloc;
pool->super_class.DeAlloc = first_free;
pool->super_class.Destroy = destroy_first_fit;
return (struct allocator*)pool;
}
int main()
{
struct allocator *al = create_fix_pool();
int *ptr = (int*)ALLOC(al,1);
FREE(al,ptr);
struct allocator *al2 = create_first_fit_pool();
ptr = (int*)ALLOC(al2,1);
FREE(al2,ptr);
return 0;
}
这样,应用只需要持有一个allocator的指针,并通过统一的ALLOC和FREE宏分配和释放内存即可.