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

自定义malloc函数中指针字节偏移异常问题排查

自定义malloc实现中的地址偏移错误问题

在实现自定义malloc函数时,出现了内存块偏移量远超预期的问题:分配4字节int时,预期空闲块从偏移20的位置开始,但实际却在320位置。以下是具体实现细节和运行现象:

堆初始化逻辑

  • 使用sysconf(_SC_PAGESIZE)获取内存页大小存入g_pagesize
  • 通过sbrk(g_pagesize)扩展堆并记录起始地址g_start
  • 调用sbrk(0)记录堆结束地址g_end

内存块结构

typedef struct header
{
    size_t m_size;
    struct header *m_next;
} header_st;

初始化时g_free指向堆起始地址,设置其m_size为g_pagesize - sizeof(header_st),g_used初始化为NULL。

分配逻辑(问题代码)

void *IR_malloc(size_t bytes_size)
{
    if (g_active == false)
        IR_init();

    size_t block_size = sizeof(header_st) + bytes_size;
    printf("Block size: %lu\n", block_size);

    header_st *blk = g_free;
    g_free += block_size; // 错误的指针算术

    blk->m_size = bytes_size;
    blk->m_next = g_used;
    
    g_used = blk;

    return g_used + sizeof(header_st); // 错误的返回地址计算
}

运行现象

第一次分配4字节后,空闲块偏移量为320而非预期的20,后续分配的偏移量也持续异常增大。


核心错误分析

  1. 指针算术错误:
    对header_st*类型指针做加法时,编译器会自动乘以sizeof(header_st)的大小。比如g_free += block_size实际等价于g_free = (header_st*)((char*)g_free + block_size * sizeof(header_st)),直接导致地址被过度偏移。
    同样,返回地址g_used + sizeof(header_st)也犯了相同错误,必须用字符指针来做字节级别的偏移计算。

  2. 空闲块大小未更新:
    分配内存后没有更新空闲块的m_size,导致后续空闲块大小显示为0,无法正确管理剩余内存。


修复后的代码

修正后的IR_malloc函数

void *IR_malloc(size_t bytes_size)
{
    if (g_active == false)
        IR_init();

    size_t block_size = sizeof(header_st) + bytes_size;
    printf("Block size: %lu\n", block_size);

    // 用char*做字节级偏移,避免指针算术的自动缩放
    header_st *blk = g_free;
    g_free = (header_st*)((char*)g_free + block_size);

    // 更新空闲块的剩余大小
    g_free->m_size = blk->m_size - bytes_size - sizeof(header_st);
    g_free->m_next = NULL;

    blk->m_size = bytes_size;
    blk->m_next = g_used;
    
    g_used = blk;

    // 返回数据区地址:跳过头部,用char*做字节偏移
    return (char*)blk + sizeof(header_st);
}

修复后的运行验证

第一次分配4字节后,空闲块会从偏移20的位置开始,后续分配也会按连续内存的预期进行,空闲块大小也会正确更新为剩余可用内存。


内容的提问来源于stack exchange,提问作者Jesper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:22:03