I have problem to correctly interpret two different ways of dynamically allocation 2D arrays in C.
This first method reads (for readability, I left out the if(arr==NULL)
checks):
double** matrix_d( long int Nrows, long int Ncols ) {
long int ii;
double** arr;
// allocate pointer to rows
arr = calloc( Nrows , (sizeof *arr));
for( ii=0 ; ii < Nrows; ii++) {
// allocate pointer to each column (?)
arr[ii] = calloc( Ncols , (sizeof **arr) );
}
return arr;
}
The second method reads (again, omitting the check of the return-value of calloc):
double** matrix_d2( long int Nrows, long int Ncols ) {
long int ii;
double** arr;
// allocate pointers to rows
arr = calloc( Nrows , (sizeof *arr) );
// allocate rows (?)
arr[0] = calloc( Nrows*Ncols, (sizeof arr) );
// set pointers to rows (?)
for( ii=0 ; ii < Nrows; ii++)
arr[ii] = (*arr + Ncols*ii);
return arr;
The comment-lines reveal probably my lack of understanding the memory allocation properly... especially the second method is somehow confusing to me (but seems to be "better" in that sense that it requires only 2 calloc/malloc calls).
Could one of you probably point me to the correct interpretation? That would be greatly appreciated! }
EDIT: there was a typo in both methods' first calloc call
Assuming the matix_d is clear.
The second function creates two areas of memory. One to store pointers to the columns and one to hold the data itself.
Every "position" in the of the first level of the array a position in the second area of memory is stored.
The method of storing and collecting the second area of memory is a little confusing. First arr[0] is assigned and is retrieved with *arr. Which is the same.
Also, when adding 1 to a pointer will increase the pointer value with the size of the data the pointer is pointing to. So ((double*)0) + 1 is the same as ((double*)sizeof(double)).
To my opinion it is better to use a local pointer to the second area of memory and use that one in the for loop.
Secondly, the sizeof is wrong. You want to allocate (cols * rows) of doubles. Use sizeof(**arr) or just sizeof(double).
double** matrix_d2( long int Nrows, long int Ncols ) {
long int ii;
double* data;
double** arr;
// allocate pointers to rows
arr = calloc( Nrows , (sizeof arr) );
// allocate data rows * cols
data = calloc( Nrows*Ncols, (sizeof **arr) );
// set pointers to rows
for( ii=0 ; ii < Nrows; ii++)
arr[ii] = (data + (Ncols*ii));
return arr;
Does this help you with the interpretation of the code?