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

实现动态泛型数组时realloc触发Segmentation fault的原因排查

段错误原因分析

你的代码核心bug出在ArrayListInit函数,直接导致ArrayListResize中调用realloc时触发段错误,具体逻辑拆解如下:

1. ArrayListInit的致命错误

你在ArrayListInit中执行了:

list = (ArrayList *)malloc(sizeof(ArrayList));

但该函数的参数ArrayList *list是值传递的指针——函数内部对list的赋值只会修改栈上的局部变量副本,完全不会影响main函数中声明的ArrayList list变量。

这意味着main里的list始终是未初始化的垃圾值:

  • list.allocated、list.len是随机的无效数值
  • list.arr是野指针

2. 触发段错误的直接路径

当调用ArrayListAppend进入ArrayListResize后:

  1. 读取list->allocated时,已经在访问未初始化的内存,属于未定义行为
  2. 执行realloc(list->arr, ...)时,list->arr是野指针,而realloc要求第一个参数要么是NULL,要么是malloc/calloc/realloc返回的有效指针,传入野指针必然触发段错误

修复方案

修正ArrayListInit逻辑

不需要在函数内malloc,直接初始化传入的指针指向的结构体:

int ArrayListInit(ArrayList *list) {
  if (list == NULL) {
    fprintf(stderr, INVALID_ARG_MSG);
    return -1;
  }
  list->allocated = 0;
  list->len = 0;
  list->arr = NULL;
  return 0;
}

补充修复ArrayListAppend的越界问题

ArrayListResize会把list->len设置为传入的新长度(即原len+1),此时直接赋值list->arr[list->len]会导致数组越界,需要改为:

int ArrayListAppend(ArrayList *list, void *item) {
  if (item == NULL) {
    fprintf(stderr, INVALID_ARG_MSG);
    return -1;
  }
  size_t new_len = list->len + 1;
  if (ArrayListResize(list, new_len) == -1) {
    return -1;
  }
  list->arr[list->len - 1] = item; // 用新len-1作为索引
  return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 20:33:34