动态二维数组创建触发free(): double free detected错误求助
动态二维数组出现double free错误的原因分析
我正在创建一个行列大小均可动态调整的二维数组,要求在main函数中分配内存,值的输入与打印操作放在另一个函数中完成。代码功能符合预期,但运行时出现free(): double free detected in tcache 2 Aborted (core dumped)错误。我仅在main函数末尾调用了一次free函数,使用GCC编译器,请问该错误的原因是什么?
代码示例
#include<stdio.h> #include<stdlib.h> #include<stdio_ext.h> void arr_value_getting_printing(int row,int col,int ** ptr) { // 获取用户输入的元素 printf("Enter the elements:\n"); for(int i = 0; i < row; i++) { for(int j = 0; j < col ; j++) { scanf("%d",&ptr[i][j]); } } // 修改二维数组的行数 char ch; __fpurge(stdin); printf("Do you want to increase the Row(y/n):\n"); scanf("%c",&ch); if(ch == 'y') { int new_row=0; printf("Enter the final row size (already 0 to %d row present):\n",row-1); scanf("%d",&new_row); int**p =realloc(ptr, new_row * sizeof(int*)); if (p != NULL) { ptr = p; // 为新行输入元素 for(int i = row ; i < new_row ; i++ ) { printf("Enter the elements for the new rows[%d]:",i); // 为新行分配内存 ptr[i] = calloc(col,sizeof(int)); for(int j = 0; j < col ; j++) { scanf("%d",&ptr[i][j]); } } row = new_row; } } // 修改二维数组的列数 __fpurge(stdin); // arr指针用于记录每行新增的列数 int * arr = calloc(row,sizeof(int)); printf("Do you want to increase the Col(y/n):\n"); scanf("%c",&ch); while(ch == 'y') { int Row,Column; printf("Which Rows col you want to increase(Rows 0 - %d):\n",row-1); scanf("%d",&Row); // 指定要修改的行 printf("Enter the new col size(current col size %d):\n",col+arr[Row]); scanf("%d",&Column); // 新的列数 int *temp = realloc (ptr[Row],Column); // 重新分配列内存 if (temp != NULL) { ptr[Row] = temp; // 更新该行新增的列数 arr[Row] = Column - col; printf("Enter the element for the new cols:\n"); for(int j = col ; j < Column ; j++) { scanf("%d",&ptr[Row][j]); } } __fpurge(stdin); printf("Do you want to continue\n"); scanf("%c",&ch); } // 打印二维数组元素 printf("Printing the updated element array elenent:\n"); for(int i = 0; i < row; i++) { for(int j = 0; j < col + arr[i] ; j++) { printf("%d ",ptr[i][j]); } printf("\n"); } } int main() { int row , col; printf("Enter the row and cols:\n"); scanf("%d %d",&row,&col); int **ptr=calloc(row,sizeof(int*)); // 创建二维数组的行指针数组 if (ptr != NULL) { for(int i = 0 ; i < row ; i++ ) { ptr[i] = calloc(col,sizeof(int)); // 创建每行的列内存 } arr_value_getting_printing(row,col,ptr); // 调用函数 } free(ptr); // 仅释放一次 }
错误原因分析
核心:realloc导致的重复释放
- 参数传递的局限性:
arr_value_getting_printing函数的第三个参数int** ptr是值传递,函数内部对ptr的修改不会同步到main函数中的ptr变量。 - realloc的内存迁移行为:当执行
int**p = realloc(ptr, new_row * sizeof(int*));时,如果原内存块无法满足扩容需求,realloc会自动释放旧内存块,并分配新的内存块返回。此时函数内部的ptr被更新为新地址,但main中的ptr仍然指向已经被释放的旧地址。 - double free触发:
main函数最后执行free(ptr)时,释放的是已经被realloc自动释放的旧内存,直接触发了double free错误。
其他潜在问题
- 内存泄漏:函数内
int * arr = calloc(row,sizeof(int));分配的内存未被释放,会造成内存泄漏。 - 行内存未释放:
main函数只释放了二维数组的行指针数组ptr,但没有释放每行的列内存ptr[i],同样会导致内存泄漏。
修复方案
- 修改函数参数为指针的指针:将函数签名改为
void arr_value_getting_printing(int row,int col,int *** ptr),让函数内部对指针的修改同步到main中:// main中调用函数时传入指针的地址 arr_value_getting_printing(row,col,&ptr); // 函数内更新指针的方式 int**p = realloc(*ptr, new_row * sizeof(int*)); if (p != NULL) { *ptr = p; // ...后续操作 } - 释放所有分配的内存:
- 在
arr_value_getting_printing函数末尾添加free(arr);,释放记录列数的数组。 - 在
main函数中,释放ptr前先循环释放每行的内存:for(int i = 0; i < row; i++) { free(ptr[i]); } free(ptr);
- 在
内容的提问来源于stack exchange,提问作者Baranitharan
相关产品推荐
相关产品推荐

