I am trying to allocate triangular array using single malloc but I could'nt find any solution for this. My structure is something like this :
a - - - -
b c - - -
d e f - -
g h i j -
k l m n o
I've made it using two malloc.
How are you planning to use the structure — what code would you write to access an array element? Also, what size of array are you dealing with?
If the array is small enough (say less than 100x100, but the boundary value is negotiable) then it makes sense to use a regular rectangular array and access that as usual, accepting that some of the allocated space is unused. If the array will be large enough that the unused space will be problematic, then you have to work harder.
Do you plan to use lt_matrix[r][c] notation, or could you use a 1D array lt_matrix[x] where x is calculated from r and c? If you can use the 1D notation, then you can use a single allocation — as shown in Technique 1 in the code below. If you use the double-subscript notation, you should probably do two memory allocations — as shown in Technique 2 in the code below. If you don't mind living dangerously, you can mix things up with Technique 3, but it isn't recommended that you use it unless you can determine what the limitations and issues are and assess for yourself whether it is safe enough for you to use. (If you ask me, the answer's "No; don't use it", but that could be regarded as being over-abundantly cautious.)
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static inline int lt_index(int r, int c) { assert(r >= c); return r * (r + 1) / 2 + c; }
int main(void)
{
int matrixsize = 5;
/* Technique 1 */
char *lt_matrix1 = malloc(matrixsize * (matrixsize + 1) / 2 * sizeof(*lt_matrix1));
assert(lt_matrix1 != 0); // Appalling error checking
char value = 'a';
for (int i = 0; i < matrixsize; i++)
{
for (int j = 0; j <= i; j++)
lt_matrix1[lt_index(i, j)] = value++;
}
for (int i = 0; i < matrixsize; i++)
{
int j;
for (j = 0; j <= i; j++)
printf("%-3c", lt_matrix1[lt_index(i, j)]);
for (; j < matrixsize; j++)
printf("%-3c", '-');
putchar('\n');
}
free(lt_matrix1);
/* Technique 2 */
char **lt_matrix2 = malloc(matrixsize * sizeof(*lt_matrix2));
assert(lt_matrix2 != 0); // Appalling error checking
char *lt_data2 = malloc(matrixsize * (matrixsize + 1) / 2 * sizeof(*lt_matrix1));
assert(lt_data2 != 0); // Appalling error checking
for (int i = 0; i < matrixsize; i++)
lt_matrix2[i] = <_data2[lt_index(i, 0)];
value = 'A';
for (int i = 0; i < matrixsize; i++)
{
for (int j = 0; j <= i; j++)
lt_matrix2[i][j] = value++;
}
for (int i = 0; i < matrixsize; i++)
{
int j;
for (j = 0; j <= i; j++)
printf("%-3c", lt_matrix2[i][j]);
for (; j < matrixsize; j++)
printf("%-3c", '-');
putchar('\n');
}
free(lt_data2);
free(lt_matrix2);
/* Technique 3 - do not use this */
void *lt_data3 = malloc(matrixsize * sizeof(int *) + matrixsize * (matrixsize + 1) / 2 * sizeof(int));
assert(lt_data3 != 0); // Appalling error checking
int **lt_matrix3 = lt_data3;
int *lt_base3 = (int *)((char *)lt_data3 + matrixsize * sizeof(int *));
for (int i = 0; i < matrixsize; i++)
lt_matrix3[i] = <_base3[lt_index(i, 0)];
value = 1;
for (int i = 0; i < matrixsize; i++)
{
for (int j = 0; j <= i; j++)
lt_matrix3[i][j] = value++;
}
for (int i = 0; i < matrixsize; i++)
{
int j;
for (j = 0; j <= i; j++)
printf("%-3d", lt_matrix3[i][j]);
for (; j < matrixsize; j++)
printf("%-3c", '-');
putchar('\n');
}
free(lt_data3);
return 0;
}
The output from the program is:
a - - - -
b c - - -
d e f - -
g h i j -
k l m n o
A - - - -
B C - - -
D E F - -
G H I J -
K L M N O
1 - - - -
2 3 - - -
4 5 6 - -
7 8 9 10 -
11 12 13 14 15
Valgrind version 3.13.0.SVN (revision 16398) gives this a clean bill of health on macOS Sierra 10.12.5 using GCC 7.1.0.
You can just malloc(width * height * sizeof(Object)) if you want to use one malloc and create one continuous array. If you want to access the (x, y) position, use: array[y * width + x].
Using two malloc just creates an array of pointers, which is a little different from a continuous array acting like a 2D array.
Related
I am writing a program that creates arrays of a given length and manipulates them. You cannot use other libraries.
First, an array M1 of length N is formed, after which an array M2 of length N is formed/2.
In the M1 array, the division by Pi operation is applied to each element, followed by elevation to the third power.
Then, in the M2 array, each element is alternately added to the previous one, and the tangent modulus operation is applied to the result of addition.
After that, exponentiation is applied to all elements of the M1 and M2 array with the same indexes and the resulting array is sorted by dwarf sorting.
And at the end, the sum of the sines of the elements of the M2 array is calculated, which, when divided by the minimum non-zero element of the M2 array, give an even number.
The problem is that the result X gives is -nan(ind). I can't figure out exactly where the error is.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
const int A = 441;
const double PI = 3.1415926535897931159979635;
inline void dwarf_sort(double* array, int size) {
size_t i = 1;
while (i < size) {
if (i == 0) {
i = 1;
}
if (array[i - 1] <= array[i]) {
++i;
}
else
{
long tmp = array[i];
array[i] = array[i - 1];
array[i - 1] = tmp;
--i;
}
}
}
inline double reduce(double* array, int size) {
size_t i;
double min = RAND_MAX, sum = 0;
for (i = 0; i < size; ++i) {
if (array[i] < min && array[i] != 0) {
min = array[i];
}
}
for (i = 0; i < size; ++i) {
if ((int)(array[i] / min) % 2 == 0) {
sum += sin(array[i]);
}
}
return sum;
}
int main(int argc, char* argv[])
{
int i, N, j;
double* M1 = NULL, * M2 = NULL, * M2_copy = NULL;
double X;
unsigned int seed = 0;
N = atoi(argv[1]); /* N равен первому параметру командной строки */
M1 = malloc(N * sizeof(double));
M2 = malloc(N / 2 * sizeof(double));
M2_copy = malloc(N / 2 * sizeof(double));
for (i = 0; i < 100; i++)
{
seed = i;
srand(i);
/*generate*/
for (j = 0; j < N; ++j) {
M1[j] = (rand_r(&seed) % A) + 1;
}
for (j = 0; j < N / 2; ++j) {
M2[j] = (rand_r(&seed) % (10 * A)) + 1;
}
/*map*/
for (j = 0; j < N; ++j)
{
M1[j] = pow(M1[j] / PI, 3);
}
for (j = 0; j < N / 2; ++j) {
M2_copy[j] = M2[j];
}
M2[0] = fabs(tan(M2_copy[0]));
for (j = 0; j < N / 2; ++j) {
M2[j] = fabs(tan(M2[j] + M2_copy[j]));
}
/*merge*/
for (j = 0; j < N / 2; ++j) {
M2[j] = pow(M1[j], M2[j]);
}
/*sort*/
dwarf_sort(M2, N / 2);
/*sort*/
X = reduce(M2, N / 2);
}
printf("\nN=%d.\n", N);
printf("X=%f\n", X);
return 0;
}
Knowledgeable people, does anyone see where my mistake is? I think I'm putting the wrong data types to the variables, but I still can't solve the problem.
Replace the /* merge */ part with this:
/*merge*/
for (j = 0; j < N / 2; ++j) {
printf("%f %f ", M1[j], M2[j]);
M2[j] = pow(M1[j], M2[j]);
printf("%f\n", M2[j]);
}
This will print the values and the results of the pow operation. You'll see that some of these values are huge resulting in an capacity overflow of double.
Something like pow(593419.97, 31.80) will not end well.
I have a graph code written a year ago which does not work now (AFAIR it worked). The graph is implemented with a square matrix which is symmetric respectively to the diagonal. I have omitted a lot of code to keep it as clear as possible, and this is still enough for the error to persist.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct
{
int **matrix;
unsigned size;
} graph;
void init(graph *gptr, int *matrix[], unsigned size)
{
gptr->size = size;
gptr->matrix = malloc(gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
gptr->matrix[i] = malloc(gptr->size * sizeof(**gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
for (unsigned j = 0; j <= i; j++)
gptr->matrix[i][j] = gptr->matrix[j][i] = matrix[i][j];
}
void add_vertex(graph *gptr, unsigned vertex)
{
for (unsigned i = 1; i < gptr->size; i++)
if (gptr->matrix[i][0] == vertex) return;
gptr->size++;
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
gptr->matrix[gptr->size - 1][0] = gptr->matrix[0][gptr->size - 1] = vertex;
for (unsigned i = 1; i < gptr->size; i++)
gptr->matrix[gptr->size - 1][i] = gptr->matrix[i][gptr->size - 1] = -1;
}
#define EDGES 7
#define RANDOM(min, max) min + rand() / ((RAND_MAX - 1) / (max - min))
#define MIN -1
#define MAX 9
int **getMatrix(unsigned size)
{
int **matrix = malloc(size * sizeof(*matrix));
for (unsigned i = 0; i < size; i++)
{
matrix[i] = malloc((i + 1) * sizeof(**matrix));
matrix[i][0] = i;
}
for (unsigned i = 1; i < size; i++)
{
for (unsigned j = 1; j < i; j++)
do
matrix[i][j] = RANDOM(MIN, MAX);
while (!matrix[i][j]);
matrix[i][i] = rand() % 2 - 1;
}
return matrix;
}
int main(void)
{
int **matrix = getMatrix(EDGES + 1);
graph x;
init(&x, matrix, EDGES + 1);
add_vertex(&x, EDGES + 1);
}
At gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix)); the program gets paused by an exception Trace/breakpoint trap. I have googled for a while, and to me it's most likely there is something wrong with my reallocation, but I have no idea what's wrong. Besides, it works fine on clang and even on online gcc 7.4 whereas fails to succeed on my gcc 8.1. Can anyone see where I'm mistaken?
On the first entry to add_vertex, gptr->size == 8 and gptr->matrix points to an array of 8 pointers to malloc'ed memory.
gptr->size++;
Now gptr->size == 9.
gptr->matrix = realloc(gptr->matrix, gptr->size * sizeof(*gptr->matrix));
And now gptr->matrix points to an array of 9 pointers. gptr->matrix[0] .. gptr->matrix[7] are the valid malloc'ed pointers from before, and gptr->matrix[8] contains uninitialized garbage.
for (unsigned i = 0; i < gptr->size; i++)
/* ERROR */
gptr->matrix[i] = realloc(gptr->matrix[i], gptr->size * sizeof(**gptr->matrix));
Since gptr->size == 9, this iterates 9 times, and on the 9th iteration, the garbage pointer gptr->matrix[8] is passed to realloc. Not good.
You could iterate the loop gptr->size - 1 times instead, and initialize gptr->matrix[gptr->size - 1] = malloc(...) separately. Or to be a little lazy and avoid code duplication, you could initialize gptr->matrix[gptr->size - 1] = NULL before this loop, keep it iterating gptr->size times, and rely on the handy feature that realloc(NULL, sz) is equivalent to malloc(sz).
I am trying to perform a simple operation. I have a matrix that is A x B by size. I have a list of indices of length C, and I want to make a C x B matrix by collecting rows from the first matrix according to the indices. i.e. index i tells me which row from the first matrix I put into row i in the second matrix.
I presorted the indices so the algorithm is input stationary: I load in the row from the A x B matrix and write that row to all the rows in the C x B matrix.
The code looks something like this:
for(int i = 0;i < A; i ++)
{
for(int k = offsets[i]; k < offsets[i+1]; k ++)
{
int dest = index1[k];
for(int j = 0;j < C/ 8; j++)
{
__m256 a = _mm256_load_ps(&input[i * C + j * 8]);
_mm256_store_ps(&output[dest * C + j * 8] ,a);
}
}
}
The code is entirely bottlenecked by write to memory.
This code is efficient when C is small. However it scales very poorly when C increases, which I surmise is due to cache behavior. (It takes 10x time when C = 1024 compared to C = 256).
I tried blocking in the C dimension:
for(int c = 0; c < C; c+= K){
for(int i = 0;i < A; i ++)
{
for(int k = offsets[i]; k < offsets[i+1]; k ++)
{
int dest = index1[k];
for(int j = 0;j < C/ 8 / K; j++)
{
__m256 a = _mm256_load_ps(&input[i * C + c + j * 8]);
_mm256_store_ps(&output[dest * C + c + j * 8] ,a);
}
}
}
}
This actually slows down the code more.
Any suggestions?
It seems the inner loop is a mere streamed copy operation. Cache wouldn't matter in such a case. Rather try using simple memcpy() instead so the compiler can yield better execution code, hopefully.
//for(int j = 0;j < C/ 8; j++)
//{
// __m256 a = _mm256_load_ps(&input[i * C + j * 8]);
// _mm256_store_ps(&output[dest * C + j * 8] ,a);
//}
memcpy(&output[dest * C], &input[i * C], C * sizeof(float));
Appendix
If satisfiable results won't be obtained, in the last resort, take C++ and replace the outer loop with parllel_for(). Then it may be possible to make the cache(or otherwise pipeline?) work a little bit better.
parallel_for(0, A, [&](const int i) {
for(int k = offsets[i]; k < offsets[i+1]; k++)
{
int dest = index1[k];
memcpy(&output[dest * C], &input[i * C], C * sizeof(float));
}
});
I met this problem when verifying whether points in a finite field GF(13) is on elliptic curve y^2 = x^3 + x + 1:
first I set the loop boundary as i<2,the results came out right.
#include <stdio.h>
#include <math.h>
void main ()
{
int a[13], b[13];
int j, i, m, k = 0;
for (i = 0; i < 2; i++)
for (j = 0; j < 13; j++)
if ((i * i * i + i + 1) % 13 == (j * j) % 13) {
a[k] = i;
b[k] = j;
k++;
}
printf ("\n There are %d points on the curve\nThe points are: ", k);
for (m = 0; m < k; m++)
printf ("\nx=%d,y=%d \n", a[m], b[m]);
}
The result is link 1
after I change the i<2 to i<13,
for(i=0;i<13;i++)
the first 4 points changed: link 2
You are entering undefined behavior. If you set a break inside the loop you will notice that k >= 13 which is outside the bounds of your arrays.
You could add some bounds checking and consider the size of your arrays.
I'd like to allocate a 3D matrix in one big chunk. It should be possible to access this matrix in the [i][j][k] fashion, without having to calculate the linearized index every time.
I think it should be something like below, but I'm having trouble filling the ...
double ****matrix = (double ****) malloc(...)
for (int i = 0; i < imax; i++) {
matrix[i] = &matrix[...]
for (int j = 0; j < jmax; j++) {
matrix[i][j] = &matrix[...]
for (int k = 0; k < kmax; k++) {
matrix[i][j][k] = &matrix[...]
}
}
}
For the single allocation to be possible and work, you need to lay out the resulting memory like this:
imax units of double **
imax * jmax units of double *
imax * jmax * kmax units of double
Further, the 'imax units of double **' must be allocated first; you can reorder the other two sections, but it is most sensible to deal with them in the order listed.
You also need to be able to assume that double and double * (and double **, but that's not much of a stretch) are sufficiently well aligned that you can simply allocate the chunks contiguously. That is going to hold OK on most 64-bit systems with type double, but be aware of the possibility that it does not hold on 32-bit systems or for other types than double (basically, the assumption could be problematic when sizeof(double) != sizeof(double *)).
With those caveats made, then this code works cleanly (tested on Mac OS X 10.10.2 with GCC 4.9.1 and Valgrind version valgrind-3.11.0.SVN):
#include <stdio.h>
#include <stdlib.h>
typedef double Element;
static Element ***alloc_3d_matrix(size_t imax, size_t jmax, size_t kmax)
{
size_t i_size = imax * sizeof(Element **);
size_t j_size = imax * jmax * sizeof(Element *);
size_t k_size = imax * jmax * kmax * sizeof(Element);
Element ***matrix = malloc(i_size + j_size + k_size);
if (matrix == 0)
return 0;
printf("i = %zu, j = %zu, k = %zu; sizes: i = %zu, j = %zu, k = %zu; "
"%zu bytes total\n",
imax, jmax, kmax, i_size, j_size, k_size, i_size + j_size + k_size);
printf("matrix = %p .. %p\n", (void *)matrix,
(void *)((char *)matrix + i_size + j_size + k_size));
Element **j_base = (void *)((char *)matrix + imax * sizeof(Element **));
printf("j_base = %p\n", (void *)j_base);
for (size_t i = 0; i < imax; i++)
{
matrix[i] = &j_base[i * jmax];
printf("matrix[%zu] = %p (%p)\n",
i, (void *)matrix[i], (void *)&matrix[i]);
}
Element *k_base = (void *)((char *)j_base + imax * jmax * sizeof(Element *));
printf("k_base = %p\n", (void *)k_base);
for (size_t i = 0; i < imax; i++)
{
for (size_t j = 0; j < jmax; j++)
{
matrix[i][j] = &k_base[(i * jmax + j) * kmax];
printf("matrix[%zu][%zu] = %p (%p)\n",
i, j, (void *)matrix[i][j], (void *)&matrix[i][j]);
}
}
/* Diagnostic only */
for (size_t i = 0; i < imax; i++)
{
for (size_t j = 0; j < jmax; j++)
{
for (size_t k = 0; k < kmax; k++)
printf("matrix[%zu][%zu][%zu] = %p\n",
i, j, k, (void *)&matrix[i][j][k]);
}
}
return matrix;
}
int main(void)
{
size_t i_max = 3;
size_t j_max = 4;
size_t k_max = 5;
Element ***matrix = alloc_3d_matrix(i_max, j_max, k_max);
if (matrix == 0)
{
fprintf(stderr, "Failed to allocate matrix[%zu][%zu][%zu]\n", i_max, j_max, k_max);
return 1;
}
for (size_t i = 0; i < i_max; i++)
{
for (size_t j = 0; j < j_max; j++)
{
for (size_t k = 0; k < k_max; k++)
matrix[i][j][k] = (i + 1) * 100 + (j + 1) * 10 + k + 1;
}
}
for (size_t i = 0; i < i_max; i++)
{
for (size_t j = 0; j < j_max; j++)
{
for (size_t k = k_max; k > 0; k--)
printf("[%zu][%zu][%zu] = %6.0f\n", i, j, k-1, matrix[i][j][k-1]);
}
}
free(matrix);
return 0;
}
Example output (with some boring bits omitted):
i = 3, j = 4, k = 5; sizes: i = 24, j = 96, k = 480; 600 bytes total
matrix = 0x100821630 .. 0x100821888
j_base = 0x100821648
matrix[0] = 0x100821648 (0x100821630)
matrix[1] = 0x100821668 (0x100821638)
matrix[2] = 0x100821688 (0x100821640)
k_base = 0x1008216a8
matrix[0][0] = 0x1008216a8 (0x100821648)
matrix[0][1] = 0x1008216d0 (0x100821650)
matrix[0][2] = 0x1008216f8 (0x100821658)
matrix[0][3] = 0x100821720 (0x100821660)
matrix[1][0] = 0x100821748 (0x100821668)
matrix[1][1] = 0x100821770 (0x100821670)
matrix[1][2] = 0x100821798 (0x100821678)
matrix[1][3] = 0x1008217c0 (0x100821680)
matrix[2][0] = 0x1008217e8 (0x100821688)
matrix[2][1] = 0x100821810 (0x100821690)
matrix[2][2] = 0x100821838 (0x100821698)
matrix[2][3] = 0x100821860 (0x1008216a0)
matrix[0][0][0] = 0x1008216a8
matrix[0][0][1] = 0x1008216b0
matrix[0][0][2] = 0x1008216b8
matrix[0][0][3] = 0x1008216c0
matrix[0][0][4] = 0x1008216c8
matrix[0][1][0] = 0x1008216d0
matrix[0][1][1] = 0x1008216d8
matrix[0][1][2] = 0x1008216e0
matrix[0][1][3] = 0x1008216e8
matrix[0][1][4] = 0x1008216f0
matrix[0][2][0] = 0x1008216f8
…
matrix[2][2][4] = 0x100821858
matrix[2][3][0] = 0x100821860
matrix[2][3][1] = 0x100821868
matrix[2][3][2] = 0x100821870
matrix[2][3][3] = 0x100821878
matrix[2][3][4] = 0x100821880
[0][0][4] = 115
[0][0][3] = 114
[0][0][2] = 113
[0][0][1] = 112
[0][0][0] = 111
[0][1][4] = 125
[0][1][3] = 124
[0][1][2] = 123
[0][1][1] = 122
[0][1][0] = 121
[0][2][4] = 135
…
[2][2][0] = 331
[2][3][4] = 345
[2][3][3] = 344
[2][3][2] = 343
[2][3][1] = 342
[2][3][0] = 341
There is a lot of diagnostic output in the code shown.
This code will work with C89 (and C99 and C11), without requiring support for variable-length arrays or VLAs — though since I declare variables in for loops, the code as written requires C99 or later, but it can easily be fixed to declare the variables outside the for loops and it can then compile with C89.
This can be done with one simple malloc() call in C (not in C++, though, there are no variable length arrays in C++):
void foo(int imax, int jmax, int kmax) {
double (*matrix)[jmax][kmax] = malloc(imax*sizeof(*matrix));
//Allocation done. Now fill the matrix:
for(int i = 0; i < imax; i++) {
for(int j = 0; j < jmax; j++) {
for(int k = 0; k < kmax; k++) {
matrix[i][j][k] = ...
}
}
}
}
Note that C allows jmax and kmax to be dynamic values that are only known at runtime. That is the ability that's missing in C++, which makes C arrays much more powerful than their C++ counterpart.
The only drawback of this approach, as WhozCraig rightly notes, is that you can't return the resulting matrix as the return value of the function without resorting to a void*. However, you can return it by reference like this:
void foo(int imax, int jmax, int kmax, double (**outMatrix)[jmax][kmax]) {
*outMatrix = malloc(imax*sizeof(**outMatrix));
double (*matrix)[jmax][kmax] = *outMatrix; //avoid having to write (*outMatrix)[i][j][k] everywhere
... //as above
}
This function would need to be called like this:
int imax = ..., jmax = ..., kmax = ...;
double (*myMatrix)[jmax][kmax];
foo(imax, jmax, kmax, &myMatrix);
That way you get full type checking on the inner two dimension sizes even though they are runtime values.
Note: This was intended to be a comment but it got too long, until it turned into a proper answer.
You can't use a single chunk of memory without performing some calculations.
Note that the beginning of each row is marked by the formula
// row_begin is the memory address of the row at index row_idx
row_begin = row_idx * jmax * kmax
And then, each column depends on where the row starts:
// column_begin is the memory address of the column
// at index column_idx of the row starting at row_begin
column_begin = row_begin + column_idx * kmax
Which, using absolute addresses (relative to the matrix pointer, of course) translates to:
column_begin = (row_idx * jmax * kmax) + column_idx * kmax
Finally, getting the k-index of an element is very straightforward, following the previous rule this could turn in an infinite recursion:
// element address = row_address + column_address + element_k_index
element_k_idx = column_begin + element_k_idx
Which translates to
element_k_idx = (row_idx * jmax * kmax) + column_idx * kmax + element_k_idx
This works for me:
void foo(int imax, int jmax, int kmax)
{
// Allocate memory for all the numbers.
// Think of this as (imax*jmax) number of memory chunks,
// with each chunk containing kmax doubles.
double* data_0 = malloc(imax*jmax*kmax*sizeof(double));
// Allocate memory for the previus dimension of pointers.
// This of this as imax number of memory chunks,
// with each chunk containing jmax double*.
double** data_1 = malloc(imax*jmax*sizeof(double*));
// Allocate memory for the previus dimension of pointers.
double*** data_2 = malloc(imax*sizeof(double**));
for (int i = 0; i < imax; i++)
{
data_2[i] = &data_1[i*jmax];
for (int j = 0; j < jmax; j++)
{
data_1[i*jmax+j] = &data_0[(i*jmax+j)*kmax];
}
}
// That is the matrix.
double ***matrix = data_2;
for (int i = 0; i < imax; i++)
{
for (int j = 0; j < jmax; j++)
{
for (int k = 0; k < kmax; k++)
{
matrix[i][j][k] = i+j+k;
}
}
}
for (int i = 0; i < imax; i++)
{
for (int j = 0; j < jmax; j++)
{
for (int k = 0; k < kmax; k++)
{
printf("%lf ", matrix[i][j][k]);
}
printf("\n");
}
}
// Deallocate memory
free(data_2);
free(data_1);
free(data_0);
}