动态内存分配的深入研究
C语言中只能通过malloc()函数及其派生函数(即calloc(), realloc()和free())动态申请内存。
malloc()函数,可以动态分配内存,且分配在堆中。
设numtype为用户需要的内存大小,则实际需要的内存大小为:numtype + mem_control_block (用户需要的内存字节数 + 一个“内存控制块”的大小)
实现流程:
1、顺序遍历所有内存块;
2、如果发现该块可用,并且该块大于实际需要的字节数,则将该内块的首地址返回,并标志位可用;
3、如果该块不可用,则选择下一块;
4、如果全都不可用,在调用sbrk()函数,通过操作系统分配一块内存。这时,malloc()函数将这块内存拓展在堆中。
流程图:
代码实现:
1 #include<stdio.h> 2 /*malloc的深入研究与编程实现,此处仅为malloc函数实现,并不是完整的程序*/ 3 /*malloc()分配内存需要在内存块中分配,则需要创建内存块结构*/ 4 struct mem_contrl_block { 5 int is_available; //标记内存块是否可用,1为可用,0为不可用 6 int size; //相应的内存块的大小,用于与实际需要的内存字节数进行比较 7 8 }; 9 10 void *managed_memory_start; //第一个内存块的首地址,堆底 11 void *last_vaild_address; //最后一个内存块最后一块内存的末地址,堆顶 12 void *malloc(size_t numbytes) //size_t应为unsigned int,在32位系统中为4个字节,在64位时为8个字节,增强其可移植性 13 { 14 void *current_location; //当前所在的内存块 15 struct mem_contrl_block *current_location_mcb; //当前块的内存控制块结构 16 void *memory_location; 17 numbytpes=numbytes+sizeof(mem_contrl_block); //实际=用户需要+一个内存控制块的大小 18 memory_location=NULL; 19 current_location=managed_memory_start; 20 while(current_location!=last_vaild_address) //遍历内存控制块 21 { 22 current_loaction_mcb=(struct mem_contrl_block *)current_location; 23 24 if(current_location_mcb->is_available){ //若可用 25 if(current_location_mcb->size>=numbytes){ //且大于实际需要的字节数 26 current_laocation_mcb->is_available=0; 27 memory_location=current_location; 28 break; 29 } 30 31 } 32 current_location=current_location+current_location_mcb->size; 33 } 34 if(!memory_location){ //没有合适的内存块 35 if(sbrk(numbytes)==-1) 36 return NULL; 37 memory_location=last_vaild_address; 38 last_vaild_address=last_vaild_location_address+numbytes; 39 current_location_mcb=memory_location; 40 current_location_mcb->is_available=0; 41 current_location_location_mcb->size=numbytes; 42 } 43 memory_location=memory_location+sizeof(struct mem_control_block); 44 return memory_location; 45 46 }
坚持做好每一个小积累,希望收获一个大成功!