Yes, but is one allowed to move a pointer inside it as they see fit? On a one-dimensional array, one can iterate through it starting with a pointer pointing to the first element and ending with a pointer pointing one position past the last element (which the user is not allowed to dereference). For multidimensional arrays, the element type is an array too (with a smaller rank than the original one), so one could perform that type of iteration with a pointer to an array. My question is whether a pointer to the underlying scalar type can freely move inside the multidimensional array without UB, since it may have to actually leave the array it was originally part of. If that's not allowed, how could one build slices and other view types?
Yes, you can do that, it's fine as long as you stay within the bounds of the indexes. Under the hood, it's a single contiguous block of memory.
Although at least with 2d arrays I prefer to just use a 1d array and index it with [x * width + y], because one problem with multidimensional arrays in C is they need multiple allocations/frees.
Double indirection arrays with multiple allocations are 25 years obsolete (ok, there are some use cases) but since C99 we prefer to do it like the parent.
In your code link you over allocate memory, sizeof *arr is enough and you need to dereference like with (*arr)[i][j].
You need to dereference it because it is a pointer to an array, if you dereference you get an array. You can also let the first dimensions decay then it looks like: