分享

C语言 内存管理器

 quasiceo 2013-02-16

C语言 内存管理器

分类: C语言 48人阅读 评论(0) 收藏 举报

          一直以来都比较关注内存管理问题,诸如碎片,泄漏,非法引用等问题成为C语言程序中的安全隐患。稍微留心一点就可以发现通常每个产品级的C程序都有专门的 内存管理接口来封装底层的内存机制,使得上层不必再纠缠于内存管理的细节。内存管理器从最初到现在写了不下20个版本,每次发现或想到新算法,都要重写一 遍,以优化性能。以下是我最近写的一款内存管理器,基于内存池,虽然池算法很普遍,不过对内存管理来说,重在细节。

          为测试该接口,专门写了自动测试脚本进行“饱和轰炸”,程序稳定运行,并未出现异常,并且根据统计显示,内存利用率很高,因为基于内存复用,因此池的个数基本稳定在3块。

 

 

/*            memmgr2.h              */

#ifndef _memmgr_2_h
#define _memmgr_2_h
 
 
#define NEWN(n,size)                 memory_new((n)*(size),__FILE__,__FUNCTION__,__LINE__)
#define NEW(size)                    NEWN(1,size)
#define NEWNP(n,ptr)                 NEWN( ( n ) , sizeof *( ptr ) )
#define NEWP(ptr)                     NEWNP(1, ( ptr ) )
#define RESIZE(ptr,size)             memory_resize(ptr,size,__FILE__,__FUNCTION__,__LINE__)
#define FREE(ptr)                     memory_free(ptr,__FILE__,__FUNCTION__,__LINE__)
 
#define Check_Memory_Status(ptr)     memory_status_string(ptr)
#define Check_Memory_Leaking()        memory_leaking_check();
 
 
extern void * memory_new ( int size ,
    const char *file , const char *func , const int line);
     
extern int   memory_free( void * ptr ,
    const char *file , const char *func , const int line);
     
extern void *memory_resize(void *ptr , int size_data ,
    const char *file , const char *func , const int line);
     
extern const char *    memory_status_string(void *ptr);
extern void         memory_leaking_check(void);
 
#endif

 

 

/*       memmgr2.c           */

#define DEBUG1
//#define DISABLE_MSG
//#define DISABLE_SHOW
#define DISABLE_D
#if 0
在设计的过程中常忘记写返回值,导致常常出问题
还有一种是return_val_if_fail,这种是有异常的时候才返回
所以,需要在后面添上正常情况的返回值,这里很容易漏掉
#endif
#include "c.h"
#include "memmgr2.h"
#include "memleak.h"
 
#define Memory_Size_512K            (1<<19)
#define Memory_Size_1M                (1<<20)
#define Memory_Size_4M                (1<<22)
#define Global_Pool_Size             Memory_Size_1M
#define Min_Data_Size                 4
 
#define Max_Chain_Array_Length         15
 
#define Max_Large_Size                Memory_Size_4M
#define Max_Chain_Block_Size         Memory_Size_512K
#define Min_Chain_Block_Size        32
 
 
#define Pointer_In_Zone(ptr,left,right)    /
    ((char*)(ptr)-(char*)(left)>=0 && (char*)(ptr)-(char*)(right)<=0)
     
struct descriptor {
    const char *file;
    const char *func;
     int         line;
     int         size;
    struct descriptor *next;
};
 
struct memory_pool {
    char        *end;
    char         *last;
    int          failed;
    struct memory_pool *current;
    struct memory_pool *next;
};
 
struct memory_chain {
    struct descriptor *deactive;
    struct descriptor *active;
    int     block_size;
};
 
static struct memory_manager {
    struct     memory_pool *pool;
    struct     descriptor     *large;
    int     max_block_size;
     
    int     large_count;
    int     pool_count;
     
    int     allocate_from_large_stamp;
    int     allocate_from_pool_stamp;
    int     allocate_from_chain_stamp;
     
    long long         allocate_memory_stamp;//pool+large
    long long       allocate_data_stamp;//memory_new size sum
    double          ratio;
    struct memory_chain chain[Max_Chain_Array_Length];
}g_mmgr;
 
//暂时不考虑内存对齐的问题
union align {
    int i;
    long l;
    long *lp;
    void *p;
    void (*fp)(void);
    float f;
    double d;
    long double ld;
};
 
static struct memory_pool *alloc_memory_pool(void);
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
static inline void inc_alloc_memory_stamp(int size)
{
    return_if_fail(size>=Min_Data_Size);
    g_mmgr.allocate_memory_stamp += size;
    if(g_mmgr.allocate_memory_stamp)
    g_mmgr.ratio=1.0*g_mmgr.allocate_data_stamp/g_mmgr.allocate_memory_stamp;
}
 
static inline void inc_alloc_data_stamp(int size)
{
    return_if_fail(size>=Min_Data_Size);
    g_mmgr.allocate_data_stamp += size;
    if(g_mmgr.allocate_memory_stamp)
    g_mmgr.ratio=1.0*g_mmgr.allocate_data_stamp/g_mmgr.allocate_memory_stamp;
}
 
#define Union_Align_Size             (sizeof(union align))
#define Align_Size(size)             (Round_Up((size),Union_Align_Size))
#define Desptr_Size                 (sizeof(struct descriptor))
#define PDesptr_Size                (sizeof(struct descriptor*))
#define Data_Package_Size(size)     (Align_Size(size)+Desptr_Size)
#define Desptr_Package_Size(desptr)    (Data_Package_Size(desptr->size))
#define Min_Package_Size             (Data_Package_Size(Min_Data_Size))
#define Data_Addr_of_Pool(pool)     (char*)((char*)pool+sizeof *(pool))
#define Pool_End(pool)                (char*)((char*)(pool)+Global_Pool_Size)
 
 
//保证是对齐后的
void *sys_new(int size)
{
    return_val_if_fail(size >= Min_Data_Size,0);
    void *ptr=calloc(1,size);
    return_val_if_fail(ptr!=0 , 0);
    inc_alloc_memory_stamp(size);
    return ptr;
}
 
void sys_free(void *ptr)
{
    return_if_fail(ptr!=0);
    if(ptr != 0)free(ptr);
}
 
static int init_memory_manager(void)
{
    Zero_Memory(&g_mmgr);
    struct memory_pool *pool=alloc_memory_pool();
    return_val_if_fail(pool!=0 , -1);
    int i;
    int chain_block_size=Min_Chain_Block_Size;
    struct memory_chain *chain=g_mmgr.chain;
    for(i=0 ; i<Max_Chain_Array_Length ; i++){
        chain[i].block_size=chain_block_size;
        chain_block_size <<= 1;
    }
    return_val_if_fail(
        chain[i-1].block_size <= Max_Chain_Block_Size , -1
    );
    g_mmgr.max_block_size=chain[i-1].block_size;
    return 0;
}
 
//size has been aligned
#define Enough_Space_for_Alloc(pool,size) /
    ( (char*)((pool)->last + (size)) <= Pool_End(pool))
 
#define Set_Desptr(desptr,_file,_func,_line,_size) do { /
            desptr->file=_file;/
            desptr->func=_func;/
            desptr->line=_line;/
            desptr->size=_size;/
        } while(0)
 
#define Ptr_Entry_Desptr(ptr)         ((struct descriptor*)((char*)(ptr)-Desptr_Size))
#define Desptr_Entry_Ptr(desptr)     ((char*)((char*)(desptr)+sizeof *(desptr)))
 
#define Show_Desptr(message,desptr)    do { /
        err_msg("/n%s/n",message);/
        Show_Value(desptr->file,s);/
        Show_Value(desptr->func,s);/
        Show_Value(desptr->line,d);/
        Show_Value(desptr->size,d);/
    }while(0)
     
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
typedef int (*compare_func)(void *data,void *val);
typedef void **(*entry_next_func)(void *data);
 
int default_compare(void *data,void *val)
{
    return (int)((char*)data-(char*)val);
}
 
static void ** search_slist(
    void **head,
    int (*compare)(void *data,void *val),
    void **(*entry_next)(void *data),
    void *val
)
{
    void **pp = 0;
    for(pp = head; pp && *pp; pp = entry_next(*pp))
        if(compare(*pp,val) == 0) break;
    return pp;
}
 
static inline struct memory_pool **entry_next_pool(struct memory_pool *pool)
{
    return pool ? &pool->next : 0;
}
 
static inline struct descriptor **entry_next_desptr(struct descriptor *desptr)
{
    return desptr ? &desptr->next : 0;
}
 
static int compare_pool_for_enough_space(
    struct memory_pool *pool , int size_package)
{
    if(Enough_Space_for_Alloc(pool,size_package)) return 0;
    if(pool->failed++>4) pool->current = pool->next;
    return -1;
}
 
static struct memory_pool *search_pool_for_enough_space(int size_package)
{
    return_val_if_fail(
        size_package >= Min_Package_Size 
     && size_package <= g_mmgr.max_block_size,
        0,
        "Allocate Size Not In Normal Range , "
        "%d out of [ %d , %d ]",
        size_package , Min_Package_Size , 
        g_mmgr.max_block_size
    );
    void **pp = search_slist(
        (void            **    )&g_mmgr.pool->current,
        (compare_func        )compare_pool_for_enough_space,
        (entry_next_func    )entry_next_pool,
        (void            *    )size_package
    ) ;
    return *(struct memory_pool **)pp ;
}
 
static int compare_pool_for_desptr(struct memory_pool *pool, 
                                    struct descriptor *desptr)
{
    void *left = Data_Addr_of_Pool(pool);
    void *right = pool->last-Min_Package_Size;
    if(Pointer_In_Zone(desptr,left, right)) return 0;
    return -1;
}
 
static struct memory_pool *search_pool_for_desptr(struct descriptor *desptr)
{
    return_val_if_fail(desptr != 0 , 0);
    void **pp = search_slist(
        (void            **    )&g_mmgr.pool,
        (compare_func        )compare_pool_for_desptr,
        (entry_next_func    )entry_next_desptr,
        (void            *    )desptr
    );
    return *(struct memory_pool **)pp;
}
 
static struct descriptor **search_large_for_desptr(struct descriptor *desptr)
{
    return_val_if_fail(desptr != 0, 0);
    void **pp = search_slist(
        (void            **    )&g_mmgr.large,
        (compare_func        )default_compare,
        (entry_next_func    )entry_next_desptr,
        (void            *    )desptr
    );
    return (struct descriptor**)pp;
}
 
static struct memory_chain *search_chain_for_data_size(int size_data)
{
    int size_package=Data_Package_Size(size_data);
    return_val_if_fail(
        size_package >= Min_Package_Size 
     && size_package <= g_mmgr.max_block_size,
        0,
        "There is no Chain for Such Data Package Size"
        " , %d out of [ %d , %d ]",
        size_package , Min_Package_Size , g_mmgr.max_block_size
    );
    struct memory_chain *chain=g_mmgr.chain;
    int i;
    for(i=0 ; i < Max_Chain_Array_Length ; i++){
        if(chain[i].block_size >= size_package) 
            return &chain[i];
    }
    return 0;
}
 
static struct memory_chain *search_chain_for_desptr(struct descriptor *desptr)
{
    return desptr ? search_chain_for_data_size(desptr->size) : 0;
}
 
static struct descriptor **search_active_for_desptr(
    struct memory_chain *chain , struct descriptor *desptr)
{
    return_val_if_fail(chain != 0 , 0);
    return_val_if_fail(desptr != 0 , 0);
     
    void **pp = search_slist(
        (void      **    )        &chain->active,
        (compare_func    )        default_compare,
        (entry_next_func)        entry_next_desptr,
        (void        *    )        desptr
    );
    return (struct descriptor **)pp;
}
 
static struct descriptor **search_chain_active_for_desptr(struct descriptor *desptr)
{
    struct memory_chain *chain=search_chain_for_desptr(desptr);
    return_val_if_fail(chain != 0 , 0);
    return search_active_for_desptr(chain,desptr);
}
 
static struct descriptor **search_chain_deactive_for_desptr(struct descriptor *desptr)
{
    struct memory_chain *chain=search_chain_for_desptr(desptr);
    return_val_if_fail(chain!=0 , 0);
    void **pp = search_slist(
        (void      **    )        &chain->deactive,
        (compare_func    )        default_compare,
        (entry_next_func)        entry_next_desptr,
        (void        *    )        desptr
    );
    return (struct descriptor **)pp;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
static int desptr_add2_chain_active(struct descriptor *desptr)
{
    return_val_if_fail(desptr != 0 , -1);
    struct memory_chain *chain=search_chain_for_desptr(desptr);
    return_val_if_fail(chain != 0 , -1);
    desptr->next = chain->active;
    chain->active = desptr;
    return 0;
}
 
#define Clear_Desptr(desptr,size)      Bzero(Desptr_Entry_Ptr(desptr),(size)-sizeof *(desptr))
 
static int desptr_add2_chain_deactive(struct descriptor *desptr,struct memory_chain *chain)
{
    return_val_if_fail(desptr!=0,-1);
    return_val_if_fail(chain!=0,-1);
    Clear_Desptr(desptr,chain->block_size);
    desptr->next=chain->deactive;
    chain->deactive=desptr;
    return 0;
}
 
static int desptr_add2_deactive(struct descriptor *desptr)
{
    return_val_if_fail(desptr!=0,-1);
    struct memory_chain *chain=search_chain_for_desptr(desptr);
    return_val_if_fail(chain!=0,-1);
    return desptr_add2_chain_deactive(desptr,chain);
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
static struct memory_pool *alloc_memory_pool(void)
{
    struct memory_pool *pool=sys_new(Global_Pool_Size);
    return_val_if_fail(pool!=0,0);
    g_mmgr.pool_count++;
    pool->last=Data_Addr_of_Pool(pool);
    pool->end=Pool_End(pool);
    pool->current=pool;
    pool->failed=0;
    pool->next=g_mmgr.pool;
    g_mmgr.pool=pool;
    return pool;
}
 
//数据大小,所以需要内部对其
static void *alloc_from_large(int size_data,
    const char *file , const char *func , const int line)
{
    return_val_if_fail(size_data >= Min_Data_Size,0);
    int size_package = Data_Package_Size(size_data);
    return_val_if_fail(
        size_package >  g_mmgr.max_block_size
     &&    size_package <= Max_Large_Size,
        0,
        "Allocate Data Package Size Not In The Normal Range"
        " , %d Out of [ %d , %d ] .",
        size_package , g_mmgr.max_block_size , Max_Large_Size
    );
    struct descriptor *desptr=(struct descriptor*)sys_new(size_package);
    return_val_if_fail(desptr!=0,0,"Allocate Large Memory Failed");
    Set_Desptr(desptr,file,func,line,size_data);
    desptr->next=g_mmgr.large;
    g_mmgr.large=desptr;
    g_mmgr.large_count++;
    g_mmgr.allocate_from_large_stamp++;
    inc_alloc_data_stamp(size_data);
    return Desptr_Entry_Ptr(desptr);
    /*
    以下函数在sys_new中就自动设置了
    int_alloc_memory_stamp(size_package);
    */
}
 
#if 0
一个bug,在pool中申请内存时通常是因为chain deactive中没有,此时不能传入size_Data
给pool,应按size_data在chain中的block_size传,否则pool会按Data_Package_Size分,
造成分配过小,这样容易造成数据覆盖
注意分清size_data,size_package,size_block区别
#endif
//数据大小,内部对齐
static void *alloc_from_pool(int size_data ,
    const char *file , const char *func , int line)
{
    int size_package = Data_Package_Size(size_data);
    struct memory_chain *chain=search_chain_for_data_size(size_data);
    int size_block = chain->block_size;
    return_val_if_fail(chain!=0,0,"Chain For Data Size Null");
    return_val_if_fail(
        size_package >= Min_Package_Size
     &&    size_package <= g_mmgr.max_block_size,
        0,
        "Allocate Data Package Size Not In The Normal Range"
        " , %d Out of [ %d , %d ] .",
        size_package , Min_Package_Size , g_mmgr.max_block_size
    );
    struct memory_pool *pool=search_pool_for_enough_space(size_block);
    if( pool == 0) pool = alloc_memory_pool();
    return_val_if_fail(pool != 0 , 0);
    return_val_if_fail(
        Enough_Space_for_Alloc(pool,size_block),0);
    struct descriptor *desptr = (struct descriptor*)pool->last;
    pool->last += size_block;
    return_val_if_fail(pool->last <= Pool_End(pool) , 0);
    Set_Desptr(desptr,file,func,line,size_data);
    int ret = desptr_add2_chain_active(desptr);
    return_val_if_fail(ret == 0 , 0);
    inc_alloc_data_stamp(size_data);
    g_mmgr.allocate_from_pool_stamp++;
    return Desptr_Entry_Ptr(desptr);
}
 
static void *alloc_from_chain_deactive(int size_data,
    const char *file , const char *func , const int line)
{
    return_val_if_fail(size_data >= Min_Data_Size,0,
        "Data Size Lower Than %d .", size_data , Min_Data_Size);
    int size_package = Data_Package_Size(size_data);
    return_val_if_fail(
        size_package >= Min_Package_Size
     &&    size_package <= g_mmgr.max_block_size,
        0,
        "Allocate Data Package Size Not In The Normal Range"
        " , %d Out of [ %d , %d ] .",
        size_package , Min_Package_Size , g_mmgr.max_block_size
    );
 
    struct memory_chain *chain=search_chain_for_data_size(size_data);
    return_val_if_fail( chain!=0, 0 , 
        "No Chain For Such Data Size %d ." , size_data);
    struct descriptor *desptr=chain->deactive;
    if(desptr == 0) return desptr;
 
    chain->deactive=desptr->next;
    Set_Desptr(desptr,file,func,line,size_data);
    desptr_add2_chain_active(desptr);
 
    g_mmgr.allocate_from_chain_stamp++;
    inc_alloc_data_stamp(size_data);
 
    return Desptr_Entry_Ptr(desptr);
}
 
void *memory_new(int size_data,
    const char *file , const char *func , const int line)
{
    err_msg(stdout,"/nAllocate Memory :");
    err_msg(stdout,"/n<< : In %s %s Line %d , Alloc Size = %d .",
        file , func , line , size_data);
    if(g_mmgr.pool==0 && g_mmgr.large==0)
        init_memory_manager();     
         
    if(size_data < Min_Data_Size) {
        err_msg(stdout,"/n>> : Failed , Data Size %d Lower Than %d",
            size_data , Min_Data_Size );
        return 0;
    }
         
    int size_package = Data_Package_Size(size_data);
    if( size_package < Min_Package_Size
         ||    size_package > Max_Large_Size){
        err_msg(stdout,"/n>> : Failed , Package Size Not Normal"
        " , %d Out of [ %d , %d ] .",
        size_package , Min_Package_Size , Max_Large_Size);
        return 0;
    }
    void *ptr=0;
    if(size_package > g_mmgr.max_block_size
        && size_package <= Max_Large_Size ){
        ptr=alloc_from_large(size_data,file,func,line);
        err_msg(stdout,"/n>> : %s , From Large "
                ", Addr = %p , Pkg_Size = %d ." , 
                ptr ? "Succeed" : "Failed" , ptr , size_package );
        return ptr;
    }
     
    struct descriptor *desptr = 0 ;
    struct memory_chain *chain = 0;
    ptr=alloc_from_chain_deactive(size_data,file,func,line);
    if(ptr != 0) {
        desptr = Ptr_Entry_Desptr(ptr);
        chain=search_chain_for_desptr(desptr);
        if(chain == 0) {
            err_msg(stdout,"/n>> : Failed , Allocate Process Exception .");
            return 0;
        }
        err_msg(stdout,"/n>> : Succeed , From Chain "
                ", Addr = %p , Pkg_Size = %d / %d / %d ." , 
                ptr , desptr->size , size_package , chain->block_size );         
        return ptr;
    }
D__
    ptr=alloc_from_pool(size_data , file , func , line);
    if(ptr != 0) {
        desptr = Ptr_Entry_Desptr(ptr);
        chain=search_chain_for_desptr(desptr);
        if(chain == 0) {
            err_msg(stdout,"/n>> : Failed , Allocate Process Exception .");
            return 0;
        }
        err_msg(stdout,"/n>> : Succeed , From Pool "
                ", Addr = %p , Size = %d / %d / %d ." ,
                ptr , desptr->size , size_package , chain->block_size );
         
        return ptr;
    }     
    err_msg(stdout,"/n>> : Failed , Allocate Process Exception .");
    return ptr;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
static int memory_free_large( struct descriptor *desptr,
    const char *file , const char *func , const int line)
{
    return_val_if_fail(desptr != 0 , -1);
    #if 0
    只有当在POOL中找不到时才会从Large中找,这时无法判定desptr是否是
    合法内存,故不能随便引用desptr->size,可能导致异常
    int size_package=Data_Package_Size(desptr->size);
    return_if_fail(
        size_package > g_mmgr.max_block_size,
        -1,
        "Desptr Not Large , Size Only %d",
        desptr->size
    );
    #endif
    struct descriptor **pp = search_large_for_desptr(desptr);
    return_val_if_fail( pp && *pp==desptr , -1);
    *pp = (*pp)->next ;
    sys_free(desptr);
    g_mmgr.large_count--;
    return 0;
}
 
static int memory_free_chain_active(struct descriptor *desptr,
    const char *file , const char *func , const int line)
{
    return_val_if_fail(desptr != 0 , -1);
    struct descriptor **pp=search_chain_active_for_desptr(desptr);
    return_val_if_fail( pp!=0 && *pp == desptr , -1);
    *pp = (*pp)->next;
    desptr_add2_deactive(desptr);
    return 0;         
}
 
int memory_free(void *ptr ,
    const char *file , const char *func , const int line)
{
    err_msg(stdout,"/nRelease Memory :");
    err_msg(stdout,"/n<< : In %s %s Line %d , Ptr Addr = %p . ",
        file , func , line , ptr);
    if(g_mmgr.pool==0 && g_mmgr.large==0)
        init_memory_manager();
     
    if(ptr==0) {
        err_msg(stdout,"/n>> : Failed , Release Ptr is Null . ");
        return -1;
    }
    struct descriptor *desptr = Ptr_Entry_Desptr(ptr);
    struct memory_pool *pool  = search_pool_for_desptr(desptr);
    if(pool==0){
        int ret=memory_free_large(desptr,file,func,line);
        if(ret!=0){
            err_msg(stdout,"/n>> : Failed , Addr = %p Not Exist .",ptr);
            return -1;
        }
    /*
        下面这句return 0极其重要,因为上面如果ret=0,那么断言不会出发,
        就会向下执行,因为desptr在memory_free_large中已经释放了,所以
        在调用下面的函数过程中会发生错误,下面memory_free_chain_active
        后面也有一个return 0,一定要注意,这时return_if_fail类的断言很容易
        出错的地方
    */
        err_msg(stdout,"/n>> : Succeed , From Large , System Works Pretty Well .");
        return 0;
    }
    int ret=memory_free_chain_active(desptr,file,func,line);
    if(ret!=0){
        err_msg(stdout,"/n>> : Failed , Addr = %p Not Exist .",ptr);
        return -1;
    }
    err_msg(stdout,"/n>> : Succeed , From Chain , System Works Pretty Well .");
    return 0;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
void *memory_resize(void *ptr , int size_data,
    const char *file , const char *func , const int line)
{
    err_msg(stdout,"/nReallocate Memory :");
    err_msg(stdout,"/n<< : In %s %s Line %d , "
              "Addr = %p , New Size = %d . ",
            file , func , line , ptr , size_data);
    if(g_mmgr.pool==0 && g_mmgr.large==0)
        init_memory_manager();
    if(ptr==0) {
        err_msg(stdout,"/n>> : Failed , Realloc Ptr is Null .");
        return ptr;
    }
    struct descriptor *desptr=Ptr_Entry_Desptr(ptr);
    struct memory_pool *pool=search_pool_for_desptr(desptr);
    struct descriptor **pp_large=0;
    struct descriptor **pp_chain=0;
    int old_size=0;
    int new_size=Data_Package_Size(size_data);
    if(pool==0) {
D__
        pp_large = search_large_for_desptr(desptr);
        if(*pp_large != desptr ) {
            err_msg(stdout,"/n>> : Failed , Addr = %p Not Exist .", ptr);
            return ptr;
        }
        old_size=Data_Package_Size(desptr->size);
        if(old_size >= new_size) {
            err_msg(stdout,"/n>> : Succeed , Ptr Not Changed , "
            "Original Size = %d .", desptr->size );
            return ptr;
        }
        *pp_large = (*pp_large)->next;
    }
    else {
D__
        struct memory_chain *chain=search_chain_for_desptr(desptr);
        if(chain == 0) {
            err_msg(stdout,"/n>> : Failed , Addr = %p Not Exist .",ptr);
            return ptr;
        }
D__
        pp_chain = search_active_for_desptr(chain,desptr);
        if( pp_chain == 0 || *pp_chain != desptr ) {
            err_msg(stdout,"/n>> : Failed , Addr = %p Not Exist .",ptr);
            return ptr;
        }
D__
        if(new_size <= chain->block_size) {
            err_msg(stdout,"/n>> : Succeed , Ptr Not Changed Yet , "
            "Chain Block Size = %d" , chain->block_size);
            return ptr;
        }
        *pp_chain = (*pp_chain)->next;
    }
    void *new_ptr=memory_new(size_data,file,func,line);
    struct descriptor *new_desptr = Ptr_Entry_Desptr(new_ptr);
D__
    Show_Value(new_desptr->size,d);
    if(new_ptr == 0) {
        err_msg(stdout,"/n>> : Failed , Reallocate Process Exception .");
        return ptr;
    }
D__
    memcpy(new_ptr , ptr , Min(desptr->size , size_data));
    new_desptr = Ptr_Entry_Desptr(new_ptr);
    if(pp_large != 0) {
D__
        sys_free(desptr);
        g_mmgr.large_count--;
    }
    else if(pp_chain != 0) {
D__     
        desptr_add2_deactive(desptr);
    }     
    new_desptr = Ptr_Entry_Desptr(new_ptr);
    err_msg(stdout,"/n>> : Succeed , Ptr Addr = %p . "
        "System Works Pretty Well ." , new_ptr);
    return new_ptr; 
}
 
const char *memory_status_string(void *ptr)
{
    return_val_if_fail(ptr!=0,0,"Ptr Null"); 
    struct descriptor **pp;
    struct descriptor *desptr = Ptr_Entry_Desptr(ptr);
D__
    struct memory_pool *pool=search_pool_for_desptr(desptr);
D__
    if(pool != 0) {
        if((char*)desptr >= (char*)pool->last) 
            return "Memory_In_Pool";
D__
        pp=search_chain_active_for_desptr(desptr);
        if(pp != 0 && *pp != 0) return "Memory_Allocated";
D__
        pp=search_chain_deactive_for_desptr(desptr);
        if(pp != 0 && *pp != 0) return "Memory_Released";
         
        return "Memory_Invalid"; 
    }
D__
    pp=search_large_for_desptr(desptr);
    if(*pp) return "Memory_Allocated_In_Large";
    return "Memory_Invalid";
}
 
static void memory_show_leaking(struct descriptor *desptr)
{
    if(desptr==0) return;
    fprintf(stdout, "/n>> : %s %s Line %d , "
        "Ptr Addr = %p , Size = %d . ",
        desptr->file , desptr->func , desptr->line , 
        Desptr_Entry_Ptr(desptr) , desptr->size);
}
 
void memory_leaking(void)
{     
    int flag=0;
    struct descriptor *desptr=g_mmgr.large;
    struct descriptor *next;
    for( ; desptr!=0 ;desptr = next) {
        if(flag==0){
            err_msg(stdout,"/nMemory Leaking Danger :");
            flag=1;
        }
        next = desptr->next;
        memory_show_leaking(desptr);
        sys_free(desptr);
        g_mmgr.large_count--;
    }
    int i;
    struct memory_chain *chain=g_mmgr.chain;
    for(i=0 ; i<Max_Chain_Array_Length ; i++)
        for( desptr=chain[i].active ; desptr ; desptr=desptr->next) {
            if(flag==0){
                err_msg(stdout,"/nMemory Leaking Danger :");
                flag=1;
            }
            memory_show_leaking(desptr);
        }
    struct memory_pool *pool=g_mmgr.pool,*next_pool;
    for( ; pool ; pool = next_pool ) {
        next_pool=pool->next;
        sys_free(pool);
        g_mmgr.pool_count--;
    }
    if(g_mmgr.large_count != 0) 
        err_msg(stdout,"/n>> : Strange Exception Exist , Large Count None Zero");
    if(g_mmgr.pool_count != 0) 
        err_msg(stdout,"/n>> : Strange Exception Exist , Pool Count None Zero");
    Zero_Memory(&g_mmgr);
    err_msg(stdout,"/n");
}
 
void memory_show()
{
    Show_Value(g_mmgr.large_count,d);
    Show_Value(g_mmgr.pool_count,d);
    Show_Value(g_mmgr.allocate_from_large_stamp,d);
    Show_Value(g_mmgr.allocate_from_pool_stamp,d);
    Show_Value(g_mmgr.allocate_from_chain_stamp,d);
    Show_Value(g_mmgr.allocate_memory_stamp,lld);
    Show_Value(g_mmgr.allocate_data_stamp,lld);
    Show_Value(g_mmgr.ratio,lf);
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多