I just started C almost a year ago and you're not helping this guy one bit.
I also wanted to use contiguous blocks of memory to make tensors, which are weird multidimensional objects. Think of three 3x3 matrices printed on 3 ortho faces of a cube.
A big problem in C is that when you make a 3D array, arr[number][column][row], which would be "number" of "column x row" matrices, the block of memory contiguous but it is not well ordered.
Have you ever wondered why you initialize an array of say arr[2][4][4]
int arr[2][4][4]=
{
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
},
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
},
};
But we all know that C starts counting at zero, so we have our matrix embedded in a larger matrix with garbage data surrounding it, and a third matrix completely of garbage data. Here's how I printed the garbage data:
#define COMPLEX 2
#define ROW 2
#define COLUMN 2
void L_print(int u[COMPLEX][ROW][COLUMN])
{
int i,j,k;
for(i=0;i<=COMPLEX;i++)
{
for(j=0;j<=ROW;j++)
{
for(k=0;k<=COLUMN;k++)
{
printf("%d ",u[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
So you get the correct data embedded in the garbage matrix. C seems to fill the garbage data slots with random garbage data, they're not all '\0' or something neat like that.
So I wanted to use pointers for runtime modifications of the size of the matrix, thus I had to make an isomorphism for my operations based on pointers.
Now when i declare a pointer and point it at the first entry of my matrix:
ptr=&a[0][0][0];
And then I print
L_ptr_print(ptr,(2*4*4));
This will spit out the proper matrix entries, which is two 4x4 matrices in this case.
But we all know that arrays start counting at zero, so an array arr[2][4][4] actually has 3*5*5 "slots" that are sizeof(int) big. So let's print the slots!
L_ptr_print(ptr,(3*5*5));
What you will get is the first 32 entries are the properly ordered matrix entries. The next 43 entries are the garbage data that you get when you fully print off the matrix arr[2][4][4].
Thus I have determined that the simplest and most elegant way to make a 3D dynamically allocated contiguous array is not not make it 3D in the first place.
Simply malloc your pointer and have the size equal to the number of array elements. So you would malloc a 32*sizeof(int) pointer:
int* ptr;
ptr=(int*)malloc(32*sizeof(int));
and then populate each element of the array like this or however u want to doit.
for(i=0;i<31;i++)
{
*(ptr+i)=i+1;
}
This can print off 32 ints and it's only 32*sizeof(int) bytes. This eliminates the need for double and triple pointers.
Or if you already have a matrix you can always just point the single pointer to each block manually, and then you don't have to worry about clearing memory because you pointer doesn't take up memory, the array does, and the pointer points to the array. But then you cannot modify the size of the array at runtime.
double (*A)[n][m] = sizeof(double[k][n][m])and forget about all this pointer-to-pointe-to-pointer stuff.