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

C语言实现自定义malloc()时链表遍历进入死循环问题排查

问题原因与修复方案

核心错误点

  • 元数据存储在栈空间导致野指针
    你在mymalloc中定义的meta_data block_meta是函数局部变量,分配在栈内存上。函数执行结束后,这块栈空间会被系统自动回收,后续函数调用会直接覆盖这块空间的内容。你将全局指针global_base指向这个局部变量的地址,相当于存储了一个野指针,多次调用mymalloc后栈空间被反复覆盖,next指针最终指向自身,就会出现无限循环、所有节点值都为最后一次赋值的4的问题。
  • 元数据没有写入分配的堆内存
    你的设计思路是元数据放在分配块的正前方,但你申请的size + block_size的堆内存(sbrk返回的空间)完全没有被用来存元数据,所有元数据都存在了马上要被回收的栈上,和分配的堆块完全没有关联。
  • 链表插入逻辑错误
    你当前写的逻辑是头插法(新节点插在链表头部),就算前面问题修复,输出顺序也会是4 -> 8 -> 10,和你预期的尾插结果相反。
  • 缺失常量定义
    代码里的block_size没有定义,按照你的设计应该等于sizeof(meta_data)。

关于.和->运算符的疑问

你这里的使用没有问题:.用于访问普通结构体变量的成员,->用于访问结构体指针指向的对象的成员。你之前定义的block_meta是普通栈上结构体变量,所以用.是正确的,不是问题诱因。

修复后的代码示例

#include <stdio.h>
#include <unistd.h>

typedef struct meta_data
{
   size_t size;
   int free;
   struct meta_data* next;
} meta_data;

#define BLOCK_SIZE sizeof(meta_data)
meta_data* global_base = NULL;

void *mymalloc(size_t size)
{
  if(size <= 0)
  {
    return NULL;
  }
  // 直接在sbrk申请的空间上存元数据
  void* request_addr = sbrk(size + BLOCK_SIZE);
  if(request_addr == (void*) -1) // sbrk申请失败判断
  {
    return NULL;
  }
  meta_data* block_meta = (meta_data*) request_addr;
  block_meta->size = size;
  block_meta->next = NULL;
  block_meta->free = 0;

  if(!global_base) // 首次分配
  {
    global_base = block_meta;
  }
  else
  {
    // 尾插逻辑:遍历到链表末尾
    meta_data* curr = global_base;
    while(curr->next != NULL)
    {
      curr = curr->next;
    }
    curr->next = block_meta;
  }
  // 返回元数据之后的用户可用空间地址
  return (void*)((char*)block_meta + BLOCK_SIZE);
}

void printList()
{
    meta_data * node = global_base;
    while (node != NULL)
    {
        printf("%zu", node->size);
        if(node->next != NULL)
        {
            printf(" -> ");
        }
        node = node->next;
    }
    printf(" \n ");
 }

int main()
{
   mymalloc(10);
   mymalloc(8);
   mymalloc(4);
   printList();
   
   return 0;
}

修复后运行输出就会和你预期的一致:10 -> 8 -> 4。

内容的提问来源于stack exchange,提问作者Umar Sheikh Salem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:24:04