自定义简易内存分配器无法合并空闲块问题求助
简易内存分配器的空闲块合并问题
我正在实现一个模拟C语言malloc()和free(void *ptr)的简易内存分配器,使用sbrk()初始化内存区域,采用首次适配算法从空闲链表查找合适块,并且将请求大小对齐到8字节的倍数。目前已解决块大小对齐问题,但空闲块合并逻辑存在问题,无法合并相邻的空闲块。
代码实现
结构体定义与对齐函数
typedef struct BLOCK BLOCK; struct BLOCK { size_t size; BLOCK *next; BLOCK *prev; int isFree; }; static BLOCK *free_list_head = NULL; size_t get_alignment(size_t user_size) { // 对齐到最近的8字节边界 return ((user_size + 7) & ~7); // 对齐到8的倍数 }
my_malloc实现
void* my_malloc(size_t user_size) { // 计算对齐后的总大小(包含块头) size_t alignment = get_alignment(user_size); size_t total_size = sizeof(BLOCK) + alignment; // 查找合适的空闲块 BLOCK *current = free_list_head; while (current != NULL) { if (current->size >= total_size) { // 找到合适块,判断是否需要拆分 if (current->size - total_size >= sizeof(BLOCK)) { BLOCK *new_free_block = (BLOCK*)((char*)current + total_size); new_free_block->size = current->size - total_size; new_free_block->next = current->next; new_free_block->prev = current; if (new_free_block->next != NULL) { new_free_block->next->prev = new_free_block; } current->size = total_size; } current->isFree = 0; return (void*)((char*)current + sizeof(BLOCK)); } current = current->next; } // 无合适空闲块,从堆中分配 void* ptr = sbrk(total_size); if (ptr == (void*)-1) { perror("sbrk"); return NULL; } // 初始化块头 BLOCK* block = (BLOCK*)ptr; block->size = total_size; block->next = NULL; block->prev = NULL; block->isFree = 0; return (void*)((char*)block + sizeof(BLOCK)); }
my_free实现
void my_free(void* ptr) { if (ptr == NULL) { return; } // 获取块头 BLOCK* block = (BLOCK*)((char*)ptr - sizeof(BLOCK)); // 标记为空闲 block->isFree = 1; // 尝试与前一个空闲块合并 if (block->prev != NULL && block->prev->isFree) { block->prev->size += block->size; // 更新前块的next指针 block->prev->next = block->next; if (block->next != NULL) { block->next->prev = block->prev; } // 当前块已合并到前块,无需后续处理当前块 } else { // 无前空闲块,若当前块是链表头则更新头指针 if (free_list_head == block) { free_list_head = block->next; if (free_list_head != NULL) { free_list_head->prev = NULL; } } } // 尝试与后一个空闲块合并 if (block->next != NULL && block->next->isFree) { block->size += block->next->size; block->next = block->next->next; if (block->next != NULL) { block->next->prev = block; } } // 将当前块插入空闲链表(如果未被合并到其他块) if (block->prev == NULL) { // 未被合并到前块,插入链表头部 if (free_list_head == NULL) { free_list_head = block; } else { block->next = free_list_head; free_list_head->prev = block; free_list_head = block; } } }
测试情况
测试代码
int main() { void* ptr1 = my_malloc(100); void* ptr2 = my_malloc(50); void* ptr3 = my_malloc(200); printf("Initial Free List:\n"); print_free_list(); my_free(ptr2); printf("Free List after freeing ptr2:\n"); print_free_list(); my_free(ptr1); printf("Free List after freeing ptr1:\n"); print_free_list(); my_free(ptr3); printf("Free List after freeing ptr3:\n"); print_free_list(); return 0; }
测试输出
Initial Free List: Free List: Free List after freeing ptr2: Free List: Block at 0x733088, size: 88 Free List after freeing ptr1: Free List: Block at 0x733000, size: 136 Block at 0x733088, size: 88 Free List after freeing ptr3: Free List: Block at 0x7330e0, size: 232 Block at 0x733000, size: 136 Block at 0x733088, size: 88
可以看到,ptr1和ptr2是相邻分配的,但释放后并未合并成一个块,问题应该出在空闲块合并逻辑或相关处理上,需要排查修复。
内容的提问来源于stack exchange,提问作者Kamrul Hassan
相关产品推荐
相关产品推荐

