3 ms·
I have one issue with the article. The way to dynamically allocate a multidimensional array in C is the following: size_t m, n; ... set m and n ... int (
by Asooka 10y ago
I have one issue with the article. The way to dynamically allocate a multidimensional array in C is the following:
size_t m, n;
... set m and n ...
int (*a)[m][n];
a = (int(*)[m][n])malloc(sizeof(*a));
Edit: and you MUST NOT REUSE OR OTHERWISE CHANGE m and n FOR THE ENTIRE LIFETIME of the array, because bad things will happen.
And you access it via
(*a)[x][y]
And you free it with
free(a);
And if you want to pass it to a function:
void do_with_array(void* raw_array, size_t m, size_t n) {
int (*array)[m][n] = (int(*)[m][n])raw_array;
... do whatever ...
}
do_with_array(a);
And I'd rather do it in Fortran, but if you ever need to do it properly in C (i.e. without using array of pointers) - now you know.
- SFJulie 10y agoTechnically you are right. Practically you are right, but the article is more right than you. I got into some fights with quite a few elite teachers/coders teaching the way of doing 2D arrays exactly as described, and they wouldn't agree the method you describe is less error prone ... because: it is tradition. (And as every person doing research know tradition is not supposed to change and that what science values). It seems absurd, but so many things are absurd these days I am not even surprised.
- Asooka 10y agoOh, the method I describe is more error prone than array of arrays, because if you ever modify the two variables you used to specify the array size, the compiler will just use the new values for array dimensions. If I had to do array of arrays though, I'd at least do something like template<typename T> T** make_2d_array(size_t m, size_t n) { // TODO: add padding for alignment, // but you're unlikely to need something aligned // on a larger extent than sizeof(void*) void *memory = malloc(m * sizeof(void*) + m * n * sizeof(T)); T** array = (T**)memory; T* data = (T*)((char*)memory + m * sizeof(void*)); for (size_t i = 0; i < m; i++) { array[i] = data + i * n; } return array; } And you can then delete the entire array with a single free().
- acqq 10y agoIf I understand, your solution, as it is, would still be wrong to be passed to the Fortran code as in Fortran the column index is faster changing. And if you would blindly translate some FORTRAN code to C with the above arrays, even if you'd get the same results the C one would be slower because of that, as the FORTRAN code could have been written with the knowledge of which index arrangement is faster.
- cygx 10y agoYou can trade some safety for syntactic convenience by using pointers to the subarrays instead of a pointer to the multidimensional array, eg void do_with_array(size_t m, size_t n, int a[static m][n]) { ... } int (*a)[n] = calloc(m, sizeof *a); do_with_array(m, n, a);
- AlexeyBrin 10y agoExcept that as of C11 variable length arrays (VLAs) are optional. So with a fully standard compliant C11 compiler your code could potentially fail. While the old way of using arrays of arrays will work with any C compiler. (Not that important if you use a pure C compiler, but your code will also fail if you use a C++ compiler.)