Reputation: 29
I have a function that allocates a two dimensional array within a function returning a pointer to the array. Creating the array requires an array of pointers each of which contains the address of a row of the two dimensional array.
How do I correctly free these two malloc()
calls outside of this function once I am done with this array?
int** allocateMatrix(int rows, int cols)
{
int* arr = malloc(rows*cols*sizeof(int));
int** matrix = malloc(rows*sizeof(int*));
int i;
for(i=0; i<rows; i++)
{
matrix[i] = &(arr[i*cols]);
}
return matrix;
}
The function is used like this:
int** 2d_arr = allocateMatrix(row,cols);
Thanks!
Upvotes: 2
Views: 121
Reputation: 17593
I suggest that you use a single malloc()
to allocate the entire memory area so as to make it easier to manage as a single pointer.
I believe the following modified version of your function should work.
int** allocateMatrix(int rows, int cols)
{
size_t sMemSize = rows*sizeof(int*) + rows*cols*sizeof(int);
int** matrix = malloc(sMemSize);
int* arr = (int *) (matrix + rows);
int i;
for(i=0; i<rows; i++)
{
matrix[i] = &(arr[i*cols]);
}
return matrix;
}
Then you can just do free(2d_arr);
where int** 2d_arr = allocateMatrix (nRows, nCols);
.
Upvotes: 0
Reputation: 223992
You can only pass to free
what was received from malloc
. So the number of calls to free
must be the same as the number of calls to malloc
.
The first row of 2d_arr
, i.e. 2d_arr[0]
, contains &arr[0*cols]
== &arr[0]
== arr
. So you want to free that and matrix
itself:
free(2d_arr[0]);
free(2d_arr);
Upvotes: 4
Reputation: 1
This will work:
void freeMatrix( int **matrix )
{
free( matrix[ 0 ] );
free( matrix );
}
Because, for i == 0
, this code
matrix[i] = &(arr[i*cols]);
sets matrix[ 0 ]
to the address of arr[0]
, which is the same value returned from the first malloc
call:
int* arr = malloc(rows*cols*sizeof(int));
It's clearer if you write matrix allocation like
int** allocateMatrix(int rows, int cols)
{
int** matrix = malloc(rows*sizeof(int*));
matrix[ 0 ] = malloc(rows*cols*sizeof(int));
int i;
for(i=1; i<rows; i++)
{
matrix[i] = &(arr[i*cols]);
}
return matrix;
}
Note the change in malloc()
order, the direct assignment to matrix[ 0 ]
, and the change in loop index to start at 1
.
Upvotes: 0