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.