C语言中标准的内存分配函数
malloc,calloc,realloc,free等
看下四个函数的原型
malloc 内存分配函数
void *malloc(unsigned size);
calloc 分配主主存储器
void *calloc(size_t nelem,size_t elsize);
realloc 重新分配主内存
void *realloc(void *ptr,unsigned newsize);
free 释放已经分配的块
void free(void *ptr);
从上面函数的原型基本上可以看出四个函数的区别
malloc和calloc
malloc 在内存动态分配中,申请1块大小为size字节的连续存储区域,calloc申请n块大小为size字节的连续的存储。
realloc 对于已经分配了地址的指针重新分配空间,ptr原有空间的地址,newsize是重新分配的内存大小。
下面介绍下三个分配内存函数的使用方式。
//1.malloc
char *p;
p=(char*)malloc(10); //因为malloc返回类型是void所以要加强制类型转换为char
//2.calloc
char *p;
p=(char*)calloc(10,sizeof(char)); //申请10块,大小为1字节的存储
//3.realloc
char* p;
p=(char*)malloc(sizeof(char)*10);
p=(char*)realloc(p,sizeof(char)*20); //原指针p,大小为10字节,重新分配20个字节
最近在读Redis源码下面看下Redis源码里面重新封装的内存管理函数
void *zmalloc(size_t size);
void *zcalloc(size_t size);
void *zrealloc(void *ptr, size_t size);
void zfree(void *ptr);
#ifdef HAVE_MALLOC_SIZE
#define PREFIX_SIZE (0)
#else
#if defined(__sun) || defined(__sparc) || defined(__sparc__)
#define PREFIX_SIZE (sizeof(long long))
#else
#define PREFIX_SIZE (sizeof(size_t))
#endif
#endif
//对于linux,使用sizeof(size_t)定长字段记录;对于sun os,使用sizeof(long long)定长字段记录。也就是上边源码中的 PREFIX_SIZE 宏
//PREFIX_SIZE 主要是为了屏蔽不同操作系统的之间的差异
void *zmalloc(size_t size) {
void *ptr = malloc(size+PREFIX_SIZE);
if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_alloc(zmalloc_size(ptr));
return ptr;
#else
*((size_t*)ptr) = size;
update_zmalloc_stat_alloc(size+PREFIX_SIZE);
return (char*)ptr+PREFIX_SIZE;
#endif
}
void *zcalloc(size_t size) {
void *ptr = calloc(1, size+PREFIX_SIZE);
if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_alloc(zmalloc_size(ptr));
return ptr;
#else
*((size_t*)ptr) = size;
update_zmalloc_stat_alloc(size+PREFIX_SIZE);
return (char*)ptr+PREFIX_SIZE;
#endif
}
void *zrealloc(void *ptr, size_t size) {
#ifndef HAVE_MALLOC_SIZE
void *realptr;
#endif
size_t oldsize;
void *newptr;
if (ptr == NULL) return zmalloc(size);
#ifdef HAVE_MALLOC_SIZE
oldsize = zmalloc_size(ptr);
newptr = realloc(ptr,size);
if (!newptr) zmalloc_oom_handler(size);
update_zmalloc_stat_free(oldsize);
update_zmalloc_stat_alloc(zmalloc_size(newptr));
return newptr;
#else
realptr = (char*)ptr-PREFIX_SIZE;
oldsize = *((size_t*)realptr);
newptr = realloc(realptr,size+PREFIX_SIZE);
if (!newptr) zmalloc_oom_handler(size);
*((size_t*)newptr) = size;
update_zmalloc_stat_free(oldsize);
update_zmalloc_stat_alloc(size);
return (char*)newptr+PREFIX_SIZE;
#endif
}
/* Provide zmalloc_size() for systems where this function is not provided by
* malloc itself, given that in that case we store a header with this
* information as the first bytes of every allocation. */
#ifndef HAVE_MALLOC_SIZE
size_t zmalloc_size(void *ptr) {
void *realptr = (char*)ptr-PREFIX_SIZE;
size_t size = *((size_t*)realptr);
/* Assume at least that all the allocations are padded at sizeof(long) by
* the underlying allocator. */
if (size&(sizeof(long)-1)) size += sizeof(long)-(size&(sizeof(long)-1));
return size+PREFIX_SIZE;
}
#endif
void zfree(void *ptr) {
#ifndef HAVE_MALLOC_SIZE
void *realptr;
size_t oldsize;
#endif
if (ptr == NULL) return;
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_free(zmalloc_size(ptr));
free(ptr);
#else
realptr = (char*)ptr-PREFIX_SIZE;
oldsize = *((size_t*)realptr);
update_zmalloc_stat_free(oldsize+PREFIX_SIZE);
free(realptr);
#endif
}