[技术| 编程·课件·Linux] c语言内存分配的深入研究

wljyy521 · 发布于 2012-06-02 00:38 · 1924 次阅读
8
我们知道在C语言中,我们动态申请内存空间的时候,使用的是malloc函数,在释放内存的时候使用的时候使用的是free函数。
那么动态内存分配的实质是什么呢?
其实系统使用的是mem_control_block(内存控制块结构)结构体管理所有已分配的内存块:
struct  mem_control_block{
      int   is_available;//表示这个块是否可用? 1:代表可用   0:代表不可用
      int size;//该块的大小
};
因此,可以简单实现和使用malloc函数,malloc函数首先是将用户申请分配的字节数加上“内存控制块”的大小,这时得到的字节数就是实际要分配的空间字节数。之后顺序遍历堆中的所有内存块,如果该块可用,并且该块的空间大小比实际要分配的空间大小要大,那么就返回该块的首地址,并且将该块设置为不可用,否则继续下一个块。   如果所有的块都不符合条件,则调用系统函数sbrk函数,通过操作系统分配一块内存。malloc函数将这块内存拓展到堆中,这时就相当于堆增长了。之后就跳过这个块内存的“内存控制结构”,将最后的一个内存的末地址重新设置。在这里使用到两个重要的全局变量:managed_memory_startlast_valid_address, 分别表示堆中的第一个内存块的首地址和最后一个内存块的最后一块内存的末地址。下面是malloc函数的实现原理:

struct mem_control_block{
int is_available;//表示这个块是否可用? 1:代表可用 0:代表不可用
int size;//该块的大小
};
void *managed_memory_start ;
void *last_valid_address;
/*malloc 函数动态分配内存
*返回值是成功分配的内存空间的首地址
*参数是用户所要分配的内存空间的大小
*/
void *malloc(size_t numbytes){
   void *current_location;//当前所在的内存块
   struct mem_control_block * current_location_mcb;//当前块的内存控制块
   void *memory_location;
   numbytes+=sizeof(struct mem_control_block );//得到实际分配的空间大小
   current_location=managed_memory_start ;//从列表头开始遍历内存块
   while(current_location!=last_valid_address){
           current_location_mcb=( struct mem_control_block * )current_location;
           if(current_location_mcb->is_available){
                 if(current_location_mcb->size>numbytes){
                         current_location_mcb->is_available=0;
                         memory_location=current_location;
                         break;
                 }
           }
         current_location+=current_location_mcb->size;
   }
   if(!memory_location){
         if(sbrk(numbytes)==-1)
                      return NULL:
         memory_location=last_valid_address;
         last_valid_address=last_valid_address+numbytes;
         current_location_mcb=memory_location;
         current_location_mcb->is_available=0;
         current_location_mcb->size=numbytes;
   }
    memory_location= memory_location+sizeof(struct mem_control_block );
    return memory_location;
}
如果sbrk函数失败,则说明内存中没有内存可用了,就返回NULL;
free函数的实现比较简单,主要的工作就是将内存块设置为可用,这时下一次调用malloc函数该块就可以再次使用了。因此在free之后,该内存块中的内容不会立刻消失,但是此时内容以不受系统保护了。下面是free函数的一个简单的实现:
void *free(void *firstbyte)//要释放内存的首地址

     struct mem_control_block *mcb;
     mcb=firstbyte-sizeof(struct mem_control_block );
     mcb->is_available=1;
     return;

到此malloc函数和free函数的基本原理就讲完了。希望对大家有所帮助;

评分

参与人数 1学分 +9 收起 理由
admin + 9 技术帝啊,膜拜啊~

查看全部评分

共收到 10 条回复
admin · #2 · 2012-6-2 00:49:11  回复 支持 反对
技术帝啊,膜拜啊~
qingyanglxy · #3 · 2012-6-2 01:08:11  回复 支持 反对
用代码说话的人NB
wljyy521 · #4 · 2012-6-2 01:11:16  回复 支持 反对
多看看都行的:lol
service · #5 · 2012-6-2 01:12:37  回复 支持 反对
果真是技术帝啊,让我们这些老人情何以堪啊
科大后浪推前浪,前浪死在沙滩上
wljyy521 · #6 · 2012-6-2 01:16:01  回复 支持 反对
以前使用的是Java,现在学一点C一点皮毛,见笑了
yaoyao · #7 · 2012-6-5 17:38:02  回复 支持 反对
学习了~:):lol:victory:
rocklee · #8 · 2012-6-7 15:34:37  回复 支持 反对
以前都不知道呀!发现只要问到实现机制,最后肯定要知道系统是怎么定义相关数据结构的。。。
rocklee · #9 · 2012-6-7 15:36:26  回复 支持 反对
以前都不知道呀!发现只要问到实现机制,最后肯定要知道系统是怎么定义相关数据结构的。。。
xuhao87 · #10 · 2012-6-7 15:41:31  回复 支持 反对
怒顶不解释:lol
malloc · #11 · 2012-6-7 17:18:41  回复 支持 反对
说的非常的好
回帖
B Color Image Link Quote Code Smilies
Command + Enter
快速回复 返回顶部 返回列表