Free double pointer using a function

不问归期 提交于 2019-12-14 03:15:42

问题


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

回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/19526356/free-double-pointer-using-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!