动态内存开辟 malloc calloc realloc free 函数

一、malloc和free

malloc和free都是c语言的库函数,一般在stdlib.h中,主要用来进行一段动态内存的分配,包括申请和释放。

malloc的函数原型为Void *malloc(size_t size),主要用于从堆上进行一段内存的申请,返回无类型的指针,需要将返回的指针转换为数据的类型,同时对申请的数据不进行初始化。

free用于将一段指针所指向的内存进行释放,free(p);由于通过malloc申请的内存在系统中记录了长度,因此不需要传入内存的长度。

 

二、malloc、calloc和realloc的比较

malloc的功能如上所述,calloc是用来进行堆空间的内存申请, 函数原型为void *calloc(size_t numElementssize_t sizeOfElement);参数为申请内存元数的个数,以及类型的长度,因此不必计算所要分配的内存的总字节数,同时alloc会对申请的内存进行初始化为0;

malloc和calloc所申请的内存均位于堆空间。malloc由于不需要对所申请的内存进行初始化,因此比calloc的效率要高。

realloc相当于改变指向动态内存区的指针的指向,让它指向新的动态内存地址;函数原型为extern void *realloc(void *mem_address, unsigned int newsize);一般分配了内存之后,如果重新分配内存,当之前分配的内存够用时指针不变,但要分配更大的内存空间时,采用尾部扩展的方式和新开辟一块内存(数据移动了),并返回内存首地址的指针。

#define MEM_BLOCK_SIZE 4096  
#define MEM_LARGE_BLOCK_THRESHOLD       40960       //>MEM_LARGE_BLOCK_THRESHOLD :requested size is large block   
#define MEM_BASE_ADDRESS                (0x90000000)  
#define MEM_ALLOC_TABLE_FIRST_ENTRY 0  
#define MAX_MEM_SIZE 7*1024*1024  
#define MEM_ALLOC_TABLE_SIZE    (MAX_MEM_SIZE/MEM_BLOCK_SIZE)  
static INT16 memory_map[MEM_ALLOC_TABLE_SIZE];  
static char isMemoryManagementReady=0;  
void *memset(void *s, int c, size_t count)  
{  
    char *xs = s;  
    while (count--)  
        *xs++ = c;  
    return s;  
}  
  
INT32 ssd_mem_init(void)  
{  
    memset(memory_map, 0, sizeof(memory_map));  
    isMemoryManagementReady=1;  
}  
INT16   ssd_mem_percentage_used()  
{  
    int used=0;  
    int i;  
    for(i=0;i<MEM_ALLOC_TABLE_SIZE;i++)  
    {  
        if(memory_map[i])  
        {  
            used++;  
        }  
    }  
    return used*100/MEM_ALLOC_TABLE_SIZE;  
}  
//return -1:FAIL  
//>=0:   return allocated address offset  
INT32 ssd_mem_malloc(UINT32 size)  
{  
    int offset=0;  
    int startEntry=MEM_ALLOC_TABLE_FIRST_ENTRY;  
    int nmemb;  
    int i;  
    if(!isMemoryManagementReady)  
    {  
           ssd_mem_init();  
    }  
      
    if(size==0)  
    {  
        return -1;  
    }  
    nmemb=size/MEM_BLOCK_SIZE;  
    if(size%MEM_BLOCK_SIZE)  
    {  
        nmemb++;  
    }  
          
    if(size > MEM_LARGE_BLOCK_THRESHOLD)  
    {  
        for(offset=startEntry;offset<MEM_ALLOC_TABLE_SIZE-nmemb;offset++)  
        {  
            if(!memory_map[offset])   
            {  
                int vacantSize=0;  
                for(vacantSize=0;vacantSize<nmemb && !memory_map[offset+vacantSize];vacantSize++);  
                if(vacantSize==nmemb)  
                {  
                    for(i=0;i<nmemb;i++)  
                    {  
                        memory_map[offset+i]=nmemb;  
                    }  
                    return (offset*MEM_BLOCK_SIZE);  
                }  
            }  
        }  
    }  
    else  
    {  
        for(offset=MEM_ALLOC_TABLE_SIZE-1;offset>=0;offset--)  
        {     
            if(!memory_map[offset] && ((offset+nmemb)<=MEM_ALLOC_TABLE_SIZE))//search start of vacant block  
            {  
                
                int vacantSize=0;  
                for(vacantSize=0;vacantSize<nmemb && !memory_map[offset+vacantSize];vacantSize++);  
                if(vacantSize==nmemb)  
                {  
                    for(i=0;i<nmemb;i++)  
                    {  
                        memory_map[offset+i]=nmemb;  
                    }  
                    return (offset*MEM_BLOCK_SIZE);  
                }  
            }  
        }  
    }  
    puts("malloc size erorr=");  
    putInt32(size);  
    return -1;  
}  
//return 0:OK  
//return 1:Out of bound  
INT32 ssd_mem_free(INT32 offset)  
{  
    int i;  
    if(!isMemoryManagementReady)  
    {  
        ssd_mem_init();  
        return 1;  
    }  
    if(offset<MAX_MEM_SIZE)  
    {  
        int index=offset/MEM_BLOCK_SIZE;  
        int nmemb=memory_map[index];  
        for(i=0;i<nmemb;i++)  
        {  
            memory_map[index+i]=0;  
        }  
        return 0;  
    }  
    else  
    {  
       return 1;//out of bound  
    }  
}  
void free(void *ptr)  
{  
    if(ptr==NULL)  
        return;  
    INT32 offset;  
    offset=ptr-MEM_BASE_ADDRESS;  
    ssd_mem_free(offset);     
}  
void * malloc(UINT32 size)  
{  
    INT32 offset;  
    offset=ssd_mem_malloc(size);  
    if(offset==-1)  
        {  
        return NULL;  
        }  
    else  
        return MEM_BASE_ADDRESS+offset;  
      
}  
  
void *realloc(void *ptr,UINT32 size)  
{  
    INT32 offset;  
    offset=ssd_mem_malloc(size);  
    if(offset==-1)  
        {  
        puts("realloc error/n");  
        return NULL;  
        }  
    else  
        {  
            memcpy((void*)(MEM_BASE_ADDRESS+offset),ptr,size);  
            free(ptr);  
            return MEM_BASE_ADDRESS+offset;       
        }  
}