You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义简易内存分配器无法合并空闲块问题求助

简易内存分配器的空闲块合并问题

我正在实现一个模拟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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:26:17