<@乌龟:>手动实现C语言运行库(1) 堆内存分配,malloc and free
最近看到了<程序员的自我修养>这本书, 对书中大部分的底层知识兴趣不算太大,不过对最后的一章,C语言运行库的实现非常的感兴趣,于是就依葫芦画瓢的实现了一下,今天花了一点时间完成了堆内存分配的内容.
就不多说太多了,直接贴贴代码,方便自己和别人日后查询,另外代码中有几处的错误,这里也标明了.
1: //定义的一个Helper结构体,描述一片空间
2: typedef struct _heap_helper
3: {4: //是否这个空间被使用
5: enum
6: { 7: HEAP_BLOCK_FREE = 0xABABABAB, 8: HEAP_BLOCK_USED = 0xCDCDCDCD, 9: } type; 10: 11: //这片空间的大小(含头部)
12: unsigned size;
13: struct _heap_helper* next;
14: struct _heap_helper* prev;
15: } heap_header; 16: 17: #define ADDR_ADD(a,o) (((char*)(a)) + o)
18: #define HEADER_SIZE (sizeof(heap_helper))
19: 20: static heap_header* list_head = NULL;
21: 22: void* malloc(unsigned size)
23: { 24: heap_header *header; 25: 26: if (size == 0)
27: {28: return NULL;
29: } 30: 31: header = list_head;32: while (header != NULL)
33: {34: //如果这片空间已经被使用,则跳至下片空间
35: if (header->type == HEAP_BLOCK_USED)
36: { 37: header = header->next;38: continue;
39: } 40: 41: //如果刚好能够容纳size的内存,则标记
42: if (header->size > size + HEADER_SIZE &&
43: header->size <= size + HEADER_SIZE * 2) 44: { 45: header->type = HEAP_BLOCK_USED;46: //原书的错误, 没有这个return
47: return ADDR_ADD(header,HEADER_SIZE);
48: } 49: 50: //如果这片空间足够大,则分割
51: if (header->size > size + HEADER_SIZE * 2)
52: { 53: heap_header* next = (heap_header*)ADDR_ADD(header,size + HEADER_SIZE); 54: next->prev = header; 55: next->next = header->next; 56: next->type = HEAP_BLOCK_FREE; 57: next->size = header->size - (size - HEADER_SIZE); 58: header->next = next; 59: header->size = size + HEADER_SIZE; 60: header->type = HEAP_BLOCK_USED;61: return ADDR_ADD(header,HEADER_SIZE);
62: } 63: header = header->next; 64: }65: return NULL;
66: } 67: 68: void free(void* ptr)
69: {70: //首先找到头部
71: heap_header* header = (heap_header*)ADDR_ADD(ptr, -HEADER_SIZE); 72: 73: //如果头部标志没有被使用
74: if (header->type != HEAP_BLOCK_USED)
75: {76: return;
77: } 78: 79: //标记
80: header->type = HEAP_BLOCK_FREE; 81: 82: //检查前面一块内存是否空,否则合并
83: if (header->prev != NULL && header->prev->type == HEAP_BLOCK_FREE)
84: { 85: header->prev->next = header->next;86: if (header->next != NULL)
87: { 88: header->next->prev = header->prev; 89: } 90: 91: header->prev->size += header->size; 92: header = header->prev; 93: } 94: 95: //检查后面一块内存是否为空,否则合并
96: if (header->next != NULL && header->next->type == HEAP_BLOCK_FREE)
97: { 98: header->size += header->next->size; 99: header->next->next->prev = header; 100: header->next = header->next->next; 101: } 102: } 103: 104: int heap_init()
105: {106: void* base = NULL;
107: heap_header* header = NULL; 108: 109: //初始堆大小默认为32M
110: unsigned heap_size = 1024 * 1024 * 32;
111: 112: //调用VirtualAlloc函数分配
113: base = VirtualAlloc(0, heap_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);114: if (base == NULL)
115: {116: return 0;
117: } 118: 119: header = (heap_header*)base; 120: header->size = heap_size; 121: header->type = HEAP_BLOCK_FREE; 122: header->next = NULL; 123: header->prev = NULL; 124: 125: list_head = header;126: return 1;
127: }
浙公网安备 33010602011771号