If only the first dimension is dynamic and the rest of them can
be static, there is a better way to create a multidimensional
array on the heap with the good, old two‑square‑bracket syntax.
But before I show you,
I want to first clarify the difference between specific types of pointers.
This is a pointer to an integer which points to the first of 4 bytes
which make an integer, so when we dereference this pointer we will
get an integer, and the pointer arithmetic of this pointer will work
in the increments of 4 bytes.
And now, what if I had an array of integers and I pointed this pointer
to this array? This is still a pointer to an integer.
It points to the first integer from this array.
It has no idea that this is an array, but we can still use it as an
array name because of the pointer arithmetic.
So, now that we made this clear, what does this line do?
This line will create an array of three pointers to integers.
It will maybe look clearer if I move this asterisk next to the data type.
But what if I put this identifier inside of parentheses together with
the asterisk? This is no longer an array declaration.
This is a pointer which points to an array of three
integers, so this is truly a pointer to an array, not a
pointer to the first element of the array.
Since it points to the array with three integers,
that means that its pointer arithmetic works in increments of 12
bytes, because 3 integers need 12 bytes in total.
Okay,
this kind of makes sense, but what will we get when we dereference this pointer?
Well,
if a dereferenced pointer to an integer gives us an integer, a
dereferenced pointer to an array should give us an array. And this is
exactly what it does, but since every array name is just a pointer to
the first element of the array,
you can think of the result of this expression as a
pointer to the first element of the array.
I hope that this makes sense, because I get tangled up in trying to explain
this terminology of a pointer to an array, because we would sometimes say that
the pointer is pointing to an array even though we mean the pointer is
pointing to the first element of that array.
If you didn't get this, maybe it will become clearer once I use it in practice.
So, let's say that we need a dynamic array where only the first
dimension is dynamic. In that case, new operator allows us to
allocate multidimensional arrays on the heap.
I could store the memory address from the heap in a simple pointer, but
I want to store it inside of a pointer to an array.
Specifically, I want a pointer to an array of three integers, because the
second static dimension is the array of three integers.
And now I can use this pointer to access each row by using an offset.
Since this is a pointer to an array of three integers, and three integers
need 12 bytes, the pointer arithmetic of this pointer will work with an
offset of 12 bytes, so adding 1 to this pointer will get us an address of
the first element from the second row.
Once we have that, we can use an offset of one integer to get
the wanted number from the specific column.
This syntax should look familiar by now.
You know that we can rewrite this to actually use two square brackets.
So now we have all of the elements placed in the same block of memory, and we
can also use the two square bracket syntax to access them.
But remember that this is only possible if the first
dimension is dynamic and others are static.
If I wanted to have another static dimension,
I can just add it to this declaration. And now I should have a pointer to
the array that contains all of these static dimensions.
I can prove this by using auto.
If I use the auto keyword here and hover over this identifier,
you can see the type of the pointer that my editor deducted.
So, to sum up, if you need a static multidimensional array,
use the regular syntax. If you need all of the dimensions to be dynamic,
make a simple array and use the formula to manually access elements.
And if only the first dimension needs to be dynamic,
you can create a multidimensional array on the heap and use auto to
deduce the correct type of pointer to an array.