简体   繁体   中英

Free double pointer using a function

So I have created and allocated memory for a double pointer using the following function:

void mallocDoubleArr(double ***arr, int size)
{
    printf("Here: %d", size);
    int i, j;

    *arr = malloc(size * sizeof(double*));

    for(i = 0; i < size; i++)
    {
        (*arr)[i]= malloc(size*sizeof(double));
        for (j = 0; j < size; j++)
        {
            (*arr)[i][j] = 0;
        }
    }
}

And I called the function using:

    double **G; //Create double pointer to hold 2d matrix

    mallocDoubleArr(&G, numNodes);

Now my question is how would I write a function to free the memory?

I tried something like this:

void freeDoubleArr(double ***arr, int size)
{
    int i, j;

    for (i = 0; i < size; i++)
        for (j = 0; j < size; j++)
            free((arr)[i]);
    free(arr);
}

It seems that you want to pass the address of a pointer to your freeDoubleArr like freeDoubleArr(&G, numnodes) (which I would rather call deleteDoubleArr ). Then you need to have

void freeDoubleArr(double ***arrptr, int size)
{
   double** arr = *arrptr;
   for (int i = 0; i < size; i++)
      free(arr[i]);
   free (arr);
   *arrptr = NULL;
}

However, you could decide that your square matrix is not represented as an array of pointers to arrays, but just as a plain array. Perhaps using flexible array members (of C99 and later) like

struct matrix_st {
   unsigned size;
   double arr[]; /* flexible array of size*size elements */
};

could be useful, with the convention that arr is really an array of size*size elements (each being a double ).

Then you can define quick access and mutator inline functions.

inline double get_element(struct matrix_st *m, int i, int j) {
   assert (m != NULL);
   unsigned s = m->size;
   assert (i>=0 && i<s && j>=0 && j<s);
   return m->arr[s*i+j];
}

inline void put_element(struct matrix_st* m, int i, int j, double x) {
   assert (m != NULL);
   unsigned s = m->size;
   assert (i>=0 && i<s && j>=0 && j<s);
   m->arr[i*s+j] = x;
}

When optimizing and with <assert.h> (see assert(3) ...) and compiling with -DNDEBUG the above accessor get_element and mutator put_element would be perhaps faster than your code.

And the matrix creation is just (to create a zero-ed matrix):

struct matrix_st* make_matrix (unsigned size) {
   struct matrix_st* m = malloc(sizeof (struct matrix_st)
                                + size*size*sizeof(double);
   if (!m) { perror("malloc"); exit(EXIT_FAILURE); };
   m->size = size;
   memset(m->arr, 0, sizeof(double)*size*size);
   return m;
 }

Then the user could just use one single call to free to free such a matrix.

BTW, if coding on Linux, compile with gcc -Wall -g and use valgrind memory leak detector and gdb debugger.

Shouldn't your free code be more like the following:

void freeDoubleArr(double ***arr, int size)
{
    int i;

    for (i = 0; i < size; i++)
        free((*arr)[i]);
    free(*arr);
}

You're not even using the 'j' parameter anywhere so the inner for loop is going to cause it to attempt to free the same area of memory size times. You also need to dereference the pointer that's passed in to get to the one that's malloc'd, in the same way you do when assigning to result of malloc into it.

Also, it would be useful when saying something doesn't work to include what specific errors you are seeing or what makes you think it isn't working properly.

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