动态分配int64_t数组realloc后输出异常/双释放错误排查
问题分析与代码错误修复
代码中的核心错误
你的array_resize函数存在三个致命问题,直接导致了不同场景下的异常:
1. realloc内存大小计算错误
realloc的第二个参数应该是新数组的总大小乘以元素字节数,但你错误地用增量resize_num来计算:
int64_t *temp = realloc(*array, sizeof(int64_t) * resize_num);
正确的计算应该基于new_size(原大小+增量):
int64_t *temp = realloc(*array, sizeof(int64_t) * new_size);
这个错误会让实际分配的内存远小于需要的总大小,后续访问超出分配范围的元素时,就会出现乱码这类未定义行为。
2. 错误释放刚分配的内存
在把*array指向temp后,你立刻执行了free(temp):
*array = temp; free(temp);
此时temp和*array指向同一块内存,free(temp)会直接释放掉刚调整好的数组内存,后续对array的操作都是在访问已释放的内存(野指针),这会导致数据错乱或内存错误。
3. 内存错误处理逻辑错误
当realloc失败时,你错误地释放了二级指针array:
free(array);
array是传入的指针的地址(二级指针),真正需要释放的是原来的数组内存*array;而且更合理的是,realloc失败时不会修改原指针,所以不需要在这里释放原内存,应该让调用者决定后续处理,避免丢失原数据。
修正后的代码
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <unistd.h> size_t array_resize(int64_t **array, size_t array_size, size_t resize_num) { size_t new_size = array_size + resize_num; // 修正:使用new_size计算内存总大小 int64_t *temp = realloc(*array, sizeof(int64_t) * new_size); if (temp == NULL) { fprintf(stderr, "failed realloc\n"); // realloc失败时原内存未被修改,直接退出即可 exit(EXIT_FAILURE); } *array = temp; // 移除错误的free(temp)调用 return new_size; } int main(void) { int array_size = 10; int64_t *array; array = malloc(array_size * sizeof(int64_t)); for (int i = 0; i < array_size; i++) { array[i] = i + 1; } for (int i = 0; i < array_size; i++) { printf("%li ", array[i]); } printf("\n"); array_size = array_resize(&array, array_size, 15); for (int i = 0; i < array_size; i++) { array[i] = i + 1; } for (int i = 0; i < array_size; i++) { printf("%li ", array[i]); } printf("\n"); free(array); return 0; }
错误对应现象解释
- 当
resize_num=15时,实际只分配了15个元素的内存,但你后续访问了25个元素,这属于内存越界访问,只是刚好这段内存没被其他数据覆盖,所以输出看起来正常,但这是典型的未定义行为,随时可能出错。 - 当
resize_num=5时,分配的内存只有5个元素,访问第11到15个元素时越界,读取到内存中的随机垃圾数据,所以出现乱码。 - 当
resize_num=130时,free(temp)释放了数组内存,后续赋值和打印都是在操作已释放的内存,最后main里再次free(array)就触发了双重释放错误,导致程序崩溃。
内容的提问来源于stack exchange,提问作者bugwriter123
相关产品推荐
相关产品推荐

