zoukankan      html  css  js  c++  java
  • C 工具库7:local_pool

    这是我的工具库中最后一个内存分配相关工具,其主要用途是,在某一函数或一个作用域中需要
    使用动态内存,出了这个作用域之后,马上就释放这些分配的内存.
    其主要工作模式是,函数开始时分配一大块内存,由分配器管理,函数中需要使用的动态内存
    全都由分配器从这块大的内存中分配出来,分配出来的内存无需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宏分配和释放内存即可.





  • 相关阅读:
    判断广播是否已注册
    Android 之使用LocalBroadcastManager解决BroadcastReceiver安全问题
    Android BroadcastReceiver 注册和反注册
    关于Android TaskAffinity的那些事儿
    文件读取方法(FileHelpers) z
    FileHelpers 用法 z
    tdf sample
    打开文件
    async/await 异步编程
    使用Topshelf创建Windows服务
  • 原文地址:https://www.cnblogs.com/sniperHW/p/2429620.html
Copyright © 2011-2022 走看看