简体   繁体   中英

releasing dynamic memory of pointer of pointers in C

I have an error while trying to release memory of dynamic array.

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;
}

after releasing the array itself, I'm trying to release the pointer of pointers (**matrix) then I get an error. debugger shows nothing special. any ideas why?

You made a couple of errors in allocating your dynamic matrix due to unclear definition of your 2D addressing.

First error in allocation, here you choose to create your matrix column dependent allocating an array of cols pointers ti int :

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

Now you should allocate an array of rows integers per each column , but you assign rows arrays of integers:

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*/
}

Up to now some compilers, or lint or even good debuggers should have told you that you where outside bounds.

But the exception triggers when you free the memory still using the wrong addressing.

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

You should pass the array of integer pointers that has a size of cols members, not rows .

Now you release what you allocated out of bounds:

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

The debugger should have complained a lot!

Then you release a now corrupted memory...

free(to_Release);

Your code should be:

#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);
}

Remember that you chosen a columns ordered matrix.

PS I forget to add that asserts are normally used for development checks and they can be removed defining the symbol NDEBUG . When you need a permanent control, like an error on allocation return, you should use standard if (condition) ErrorHandling(...); .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM