实现动态泛型数组时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后:
- 读取
list->allocated时,已经在访问未初始化的内存,属于未定义行为 - 执行
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
相关产品推荐
相关产品推荐

