redis源码阅读-数据结构篇-内存管理

1. 内存管理mallocfree

void *zmalloc(size_t size);				// 对malloc的封装
void *zcalloc(size_t size);				// 对calloc的封装
void *zrealloc(void *ptr, size_t size);               // 对realloc的封装
void zfree(void *ptr);					// 对free的封装

zmalloc

// 与普通malloc...的区别主要在于有没有prefix
// 用户主动维护了prefix,表示操作内存的size
#define PREFIX_SIZE (sizeof(size_t))			
void *zmalloc(size_t size) {
     // 多malloc一个prefix的大小
    void *ptr = malloc(size+PREFIX_SIZE);
    // oom
    if (!ptr) zmalloc_oom_handler(size); 
    // prefix的大小置为操作内存的大小
    *((size_t*)ptr) = size;	
    // 返回紧接prefix后的指针
    return (char*)ptr+PREFIX_SIZE;				
}

zcalloc

void *zcalloc(size_t size) {
    // 第二个参数表示要分配的字节单元大小
    // 第一个参数表示要分配多少个这样的字节单元
    // 初始化为0
    void *ptr = calloc(1, size+PREFIX_SIZE); 
    if (!ptr) zmalloc_oom_handler(size);
    *((size_t*)ptr) = size;
    return (char*)ptr+PREFIX_SIZE;
}	

zrealloc

void *zrealloc(void *ptr, size_t size) {
    void *realptr;
    void *newptr;
    if (ptr == NULL) return zmalloc(size);
    // 真正的指针在ptr - PREFIX_SIZE
    realptr = (char*)ptr-PREFIX_SIZE;
    // 第一个参数是指向旧的堆内动态分配的内存,
    // 第二个参数表示重新分配的大小
    // 用来扩大动态分配区域,第二个参数比原来size大
    // 申请一块更大内存,并将原来空间的内容依次复制进新的地址空间
    // 旧的内存将会自动释放
    newptr = realloc(realptr,size+PREFIX_SIZE);			
    if (!newptr) zmalloc_oom_handler(size);
    *((size_t*)newptr) = size;
    return (char*)newptr+PREFIX_SIZE;
}

zfree

void zfree(void *ptr) {
    void *realptr;
    if (ptr == NULL) return;
    realptr = (char*)ptr-PREFIX_SIZE;
   	// 释放真正的指针
    free(realptr);																	
}
posted @ 2021-06-09 22:22  Jamgun  阅读(43)  评论(0编辑  收藏  举报