代码之家  ›  专栏  ›  技术社区  ›  Ofek Pintok

释放C中指针指针的动态内存

  •  0
  • Ofek Pintok  · 技术社区  · 6 年前

    尝试释放动态数组的内存时出错。

    void Ex()
    {
     int **Matrix = dyn_matrix_allocation(rows, cols);
    .
    .
    .
        free_My_Dyn_Mem(Matrix, rows);
    }
    
    void free_My_Dyn_Mem(int **to_Release, int size)
    {
        int i;
        for (i = 0; i < size; i++)
            free(to_Release[i]);
    //free(to_Release); - If I do this, the program crash.
    }
    
    void **dyn_matrix_allocation(int rows, int cols)
    {
        void **matrix = (void**)calloc (sizeof(int*), cols);
        assert(matrix); /*calloc worked*/
        int i;
        for (i = 0; i < rows; i++)
        {
            matrix[i] = (int*)calloc(sizeof(int), rows);
            assert(matrix[i]); /*calloc worked*/
        }
        return matrix;
    }
    

    在释放数组本身之后,我尝试释放指针指针 (**matrix) 然后我得到一个错误。调试器没有显示任何特殊内容。知道为什么吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Frankie_C    6 年前

    由于2D寻址的定义不明确,您在分配动态矩阵时出现了几个错误。

    分配中的第一个错误,这里您选择创建依赖于矩阵列的分配 cols 指针ti int :

    void **matrix = (void**)calloc (sizeof(int*), cols);
    

    现在你 应分配一个数组 rows 每列整数 ,但您指定 整数数组:

    for (i = 0; i < rows; i++)  //Should be for (i = 0; i < cols; i++)
    {
        matrix[i] = (int*)calloc(sizeof(int), rows);
        assert(matrix[i]); /*calloc worked*/
    }
    

    到目前为止,一些编译器、lint甚至优秀的调试器都应该告诉您超出了范围。

    但当您仍然使用错误的寻址释放内存时,会触发异常。

    void Ex()
    {
     int **Matrix = dyn_matrix_allocation(rows, cols);
    .
    .
    .
        free_My_Dyn_Mem(Matrix, rows);  //But you allocated cols pointers...
    }
    

    您应该传递大小为的整数指针数组 科尔斯 成员,而不是

    现在,您可以释放您分配的超出范围的内容:

    for (i = 0; i < size; i++)
        free(to_Release[i]);
    

    调试器应该抱怨很多!

    然后释放一个现已损坏的内存。。。

    free(to_Release);
    

    您的代码应为:

    #include <stdlib.h>
    #include <assert.h>
    
    void free_My_Dyn_Mem(int **to_Release, int size)
    {
        int i;
        for (i = 0; i < size; i++)
            free(to_Release[i]);
        free(to_Release);   //- If I do this, the program crash.
    }
    
    int **dyn_matrix_allocation(int rows, int cols)
    {
        int **matrix = calloc(sizeof(int *), cols);
        assert(matrix); /*calloc worked */
        int i;
        //for (i = 0; i < rows; i++)
        for (i = 0; i < cols; i++)
        {
            matrix[i] = calloc(sizeof(int), rows);
            assert(matrix[i]);  /*calloc worked */
        }
        return matrix;
    }
    
    void Ex(void)
    {
        int rows = 100;
        int cols = 20;
        int **Matrix = dyn_matrix_allocation(rows, cols);
    //.
    //.
    //.
        //free_My_Dyn_Mem(Matrix, rows);
        free_My_Dyn_Mem(Matrix, cols);
    }
    

    请记住,您选择了列排序矩阵。

    P、 我忘了补充一点,断言通常用于开发检查,它们可以在定义符号时删除 NDEBUG 。当您需要永久控制时,如分配返回时出错,应使用标准 if (condition) ErrorHandling(...);