typedef struct os_mem //内存控制块 { void *OSMemAddr; //指向内存分区的首地址 void *OSMemFreeList; //该内存分区的block链表的表头 INT32U OSMemBlkSize; //每一个block的大小 INT32U OSMemNBlks; //该分区中block的数目 INT32U OSMemNFree; //该分区中空闲block的数目 } OS_MEM;
//内存分区的首地址 plink = (void **)addr; //第二个block的地址 pblk = (INT8U *)((INT32U)addr + blksize); for (i = 0; i < (nblks - 1); i++) { //每一个block的开头存放下一个block的首地址 *plink = (void *)pblk; //更新指针而已 plink = (void **)pblk; pblk = (INT8U *)((INT32U)pblk + blksize); } //最后一个block指向NULL *plink = (void *)0;上述代码的核心就在于*pblink = (void*)pblk;每一个block开头存放下一个block的地址,这样便把所有的block组织成了一条链表。
//还有内存可以分配 if (pmem->OSMemNFree > 0) { //获取一个block pblk = pmem->OSMemFreeList; //使链表表头指向这个block的下一个block pmem->OSMemFreeList = *(void **)pblk; //更新内存块的数量 pmem->OSMemNFree--; }代码的核心就在于pmem->OSMemFreeList = *(void **)pblk; 因为pblk指向该block,该block的首地址存放的是下一个block的地址,所以这句实际上让空余链表的表头指向了下一个block。
//在将要删除的内存块的首地址存放block表头的地址 *(void **)pblk = pmem->OSMemFreeList; //更新链表表头 pmem->OSMemFreeList = pblk; //更新可用内存块的数目 pmem->OSMemNFree++;代码的核心就是*(void **)pblk = pmem->OSMemFreeList;在将要删除的block的开头存放链表的表头,即相当于把这个block链接到了空余链表的表头中。
原文:http://blog.csdn.net/csu_stackoverflow/article/details/24347041