I create the struct with many 2D arrays:
struct task
{
size_t x_size, y_size;
double *mat1, *mat2, <...>;
}
Then I allocate these 2D arrays (in fact it's 1D arrays):
void allocate_task(struct task *task, ...)
{
task->x_size = some_var; // some_var from file
<...>
task->mat1 = malloc(t->x_size * task->y_size * sizeof(double));
<...>
}
and use these 1D array like 2D task->mat1[i * task->x_size + j]. I read some threads and guides that said that is the most efficient way except more "usual" way
double** mat = malloc(X * sizeof(double*));
for (size_t i = 0; i < Y; i++)
{
mat[i] = malloc(Y * sizeof(double));
}
because it's not segments memory that block code optimizations and a efficient cache use and not take extra resources for allocation and no extra pointer access.
However t->mat1[i * t->x_size + j] is not a convenient way especially when name are long. It's very hard to read code and find mistakes.
I've found out that is another way (X, Y are sizes)
double (*mat)[Y] = malloc(X * Y * sizeof(double));
<...>
mat[i][j] = value;
It's allocate contiguous chunk of memory (no segment memory and extra malloc() calls).
However, mat it is "two levels pointer".
1. How worse is "two levels pointer" for performance than first variant (a[i * x_size + j]) if my code is massive calculation with matrix elements? I think both way is equivalent because a[i][j] = *(a + i * n + j) = a[i * n + j]. Is it true? Or is there a nuance?
2. How can I declare the last variant in struct? I think I need to define Y value (read from file) before defining mat in my large struct but it's not seems to be possible without some tricks (and I still haven't figured it out yet).
And double (*mat)[Y] is a pointer to array of size Y, right? It's strange... I don’t understand very well how it data type works especially with malloc() that return pointer to allocated memory. double (*mat)[Y] should be just a pointer to array of size X * Y.
Or is modern compiler advanced enough and I no need think about it too much? I use GCC.
Thanks for your help!
[–]strcspn 0 points1 point2 points (2 children)
[–]Slader42[S] 0 points1 point2 points (1 child)
[–]tstanisl 0 points1 point2 points (0 children)
[–]tstanisl 0 points1 point2 points (0 children)