1. 内存管理malloc
和free
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);
}