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

动态二维数组创建触发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导致的重复释放

  1. 参数传递的局限性:arr_value_getting_printing函数的第三个参数int** ptr是值传递,函数内部对ptr的修改不会同步到main函数中的ptr变量。
  2. realloc的内存迁移行为:当执行int**p = realloc(ptr, new_row * sizeof(int*));时,如果原内存块无法满足扩容需求,realloc会自动释放旧内存块,并分配新的内存块返回。此时函数内部的ptr被更新为新地址,但main中的ptr仍然指向已经被释放的旧地址。
  3. double free触发:main函数最后执行free(ptr)时,释放的是已经被realloc自动释放的旧内存,直接触发了double free错误。

其他潜在问题

  1. 内存泄漏:函数内int * arr = calloc(row,sizeof(int));分配的内存未被释放,会造成内存泄漏。
  2. 行内存未释放:main函数只释放了二维数组的行指针数组ptr,但没有释放每行的列内存ptr[i],同样会导致内存泄漏。

修复方案

  1. 修改函数参数为指针的指针:将函数签名改为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;
        // ...后续操作
    }
    
  2. 释放所有分配的内存:
    • 在arr_value_getting_printing函数末尾添加free(arr);,释放记录列数的数组。
    • 在main函数中,释放ptr前先循环释放每行的内存:
      for(int i = 0; i < row; i++)
      {
          free(ptr[i]);
      }
      free(ptr);
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 17:09:49