patterncMinor
Allocating a contiguous block of memory for an array
Viewed 0 times
arrayblockformemorycontiguousallocating
Problem
I try to work with a contiguous block of memory, to create an array (2D) whose SIZE is not known at compile time (before c99) so no variable-length arrays are involved here.
I came up with the following:
Which gives me the following:
Is this the right approach?
I came up with the following:
#include
#include
int main(void){
unsigned int row, col,i, j, k;
int l = 0;
int *arr;
printf("Give the ROW: ");
if ( scanf("%u",&row) != 1){
printf("Error, scanf ROW\n");
exit(1);
}
printf("Give the COL: ");
if ( scanf("%u",&col) != 1){
printf("Error, scanf COL\n");
exit(2);
}
arr = malloc(sizeof *arr * row * col);
if(arr == NULL){
printf("Error, malloc\n");
exit(3);
}
for ( i = 0; i < row ; i++){
for ( j = 0 ; j < col ; j++){
arr[i * col + j] = l;
l++;
}
}
for (k = 0 ; k < (row * col) ; k++){
printf("%d ",arr[k]);
}
free(arr);
}Which gives me the following:
Give the ROW: 6
Give the COL: 3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17Is this the right approach?
Solution
Of course this in not a true 2d array, just a 1d array indexed using
This is an OK approach. When able, I prefer an array of pointers to an array of
-
Modest extreme case:
Pedantically, even
-
Suggest using
-
Error messages are better sent to
-
Idea: Using a
-
Minor:
-
A key comment missing is: is this array row or column major? With some analysis, that is discernible, but from a header only interface, knowing which dimension moves in the smallest steps is important in how higher level code will want to use this array for cache hit efficiency.
-
Coding style: No need to introduce a variable until ready for assignment. Consider the 2nd style.
arr[i * col + j].This is an OK approach. When able, I prefer an array of pointers to an array of
ints, as it is usually more flexible to the tasks I tackle. YMMV.-
Modest extreme case:
sizeof arr row col is multiplied in the right order. When row or col is int/unsigned, good to use sizeof arr first as that is type size_t and the subsequent multiplication will then happen at least using size_t math. The concern being that with unsigned row, col, row*col calculated first could overflow using unsigned math, but not size_t math. Pedantically, even
sizeof arr row * col can overflow. Should code need to detect this, the reasonable approach is to use the widest unsigned types like unsigned long long or uintmax_t. (Other more pedantic methods exist.) assert(1LLU * sizeof *arr * row * col < SIZE_MAX);-
Suggest using
size_t for row, col, i, j instead of any other type. size_t is the Goldilocks type for array indexes - not too narrow, not too wide. -
Error messages are better sent to
stderr. 2 advantages: will not get lost in code's typical stdout output and the stderr stream is flushed ensuring output is not mixed after later input.-
Idea: Using a
arr = 0; after the free(arr); has merit when the free'd variable is still in scope for a long time. Although not needed, a decent compiler will optimized it out, but errant subsequent use is easier to detect when arr == NULL than arr = some_freed_value.-
Minor:
printf("%d ",arr[k]); in a loop is sometimes a problem when trying to print more than some environmental limit number (e.g. 4095) of characters on the same line. Liberal use of fflush(stdout); or including a '\n' in the text usually solves this.-
A key comment missing is: is this array row or column major? With some analysis, that is discernible, but from a header only interface, knowing which dimension moves in the smallest steps is important in how higher level code will want to use this array for cache hit efficiency.
-
Coding style: No need to introduce a variable until ready for assignment. Consider the 2nd style.
// int *arr;
// ... many lines
// arr = malloc(sizeof *arr * row * col);
... many lines
int *arr = malloc(sizeof *arr * row * col);Code Snippets
assert(1LLU * sizeof *arr * row * col < SIZE_MAX);// int *arr;
// ... many lines
// arr = malloc(sizeof *arr * row * col);
... many lines
int *arr = malloc(sizeof *arr * row * col);Context
StackExchange Code Review Q#129207, answer score: 3
Revisions (0)
No revisions yet.