what would be the impact in accessing of array or in memory allocation for these two cases:
1.
int **arr;
arr = malloc( sizeof(int) * row * column );
2.
int **arr;
arr = malloc( sizeof(*arr) * row);
for(i=0; i<row; i++)
arr[i] = malloc( sizeof( **arr) * column));
A 2D array can be dynamically allocated in C using a single pointer. This means that a memory block of size row*column*dataTypeSize is allocated using malloc and pointer arithmetic can be used to access the matrix elements.
C malloc() method The “malloc” or “memory allocation” method in C is used to dynamically allocate a single large block of memory with the specified size.
piBuffer = malloc( nrows * sizeof(int *)); int ** piBuffer = NULL; piBuffer = malloc( nrows * sizeof(int *)); int ** piBuffer = NULL; piBuffer = malloc( nrows * sizeof(int *)); Allocate memory for each row-column using the malloc().
Firstly, the "impact" is that your first method is broken. It will not work through an int **
pointer.
In order to allocate a 2D array in one shot as you are trying to do it in your first method, you actually have to allocate a 1D array of sufficient size
int *arr = malloc( row * column * sizeof *arr );
// Note: `int *`, not `int **`
and perform access by manual index re-calculation, e.g. instead of doing arr[i][j]
you have to do arr[i * column + j]
.
Trying to store the allocated pointer in int **arr
and then access your array as arr[i][j]
will simply lead to crashes.
Secondly, your second method is OK. It is just that in the second method your are not really required to allocate the second-level memory by multiple independent malloc
calls. You can allocate the whole second-level memory in one shot
int **arr = malloc( row * sizeof *arr );
int *arr_data = malloc( row * column * sizeof *arr_data );
and then just distribute that pre-allocated second-level memory between the rows
for (i = 0; i < row; i++)
arr[i] = arr_data + i * column;
(Of course, you can allocate the rows independently, if you wish so. It will also work. The reason I wanted to allocate them in one shot is to better illustrate the similarity between the first and the second approach, as commented below.)
Now, by looking at these two methods you can easily see that both of them essentially do the same thing. The only difference is that in the first method you find the beginning of the row on-the-fly by calculating arr + i * column
every time (note that arr[i * column + j]
is equivalent to (arr + i * column)[j]
). In the second method you pre-calculate all row beginnings in advance by using the same arr_data + i * column
formula, and store them for further usage in a separate "row index" array arr
.
So, it basically boils down to trade-off between memory usage (first method requires less memory) and speed (the second method is potentially, but not necessarily, faster). At the same time the second method supports the "natural" syntax for 2D array access - arr[i][j]
, while in the first method you have to use more convoluted 1D access syntax with index recalculation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With