#include <stdio.h> #include <unistd.h> #include <stdbool.h> typedef struct mem_control_block //内存控制块 { bool free; //自由标志 struct mem_control_block* prev; //前向指针 size_t size; //块大小 }MCB; MCB* g_top; //内存栈顶指针 // +----------------------+ g_top // v | | // +------+------------+--|---+------------+------+------------+ // | prev | | prev | | prev | | // | free | | free | | free | | // | size | | size | | size | | // +------+------------+------+------------+------+------------+ // MCB |<-- size -->| void* my_malloc(size_t size) { MCB* mcb; for(mcb = g_top; mcb; mcb = mcb->prev) if(mcb->free && mcb->size >= size)//寻找可用空块 break; if(!mcb) //如果没有可用空块 { mcb = sbrk(sizeof(MCB) + size); //增量分配size大小内存 if(mcb == (void*)-1) //如果分配失败,打印错误信息 { perror("sbrk"); return NULL; } mcb->prev = g_top; //调整前向指针 mcb->size = size; //大小 g_top = mcb; //调整栈顶指针 } mcb->free = false; //无论用原来空块还是新分配的块,都标记为不可用 return mcb + 1; //返回实际分配的内存起始地址 } void my_free(void* ptr) { if(!ptr) return; MCB* mcb = (MCB*)ptr - 1; //取控制块起始地址, //注意:ptr为实际可用内存起始地址 mcb->free = true; //块标记为可用 //在栈中查找连续内存块 for(mcb = g_top; mcb->prev; mcb = mcb->prev) if(!mcb->free) break; //释放整个栈所有内存块 if(mcb->free) { g_top = mcb->prev; brk(mcb); //修改内存块末尾地址 } else //释放连续的标记为true的内存块 { g_top = mcb; brk((void*)mcb + sizeof(MCB) + mcb->size); } } //测试 int main(void) { int* pa[10]; size_t size = sizeof(pa) / sizeof(pa[0]), i, j; for(i = 0; i < size; ++i) { if(!(pa[i] = (int*)my_malloc((i+1) * sizeof(int)))) { perror("my_malloc"); return -1; } for(j = 0; j <= i; ++j) pa[i][j] = j; } for(i = 0; i < size; ++i) { for(j = 0; j <= i; ++j) printf("%d ", pa[i][j]); printf("\n"); } for(;;) { my_free(pa[--i]); if(! i) break; } return 0; }
原文地址:http://blog.csdn.net/liyuan_669/article/details/40016901