Dill - 1 year ago 110
C Question

# Create a pointer to two-dimensional array

I need a pointer to a static 2-dimensional array. How is this done?

``````static uint8_t l_matrix[10][20];

void test(){
uint8_t **matrix_ptr = l_matrix; //wrong idea
}
``````

I get all kinds of errors like:

• warning: assignment from incompatible pointer type

• subscripted value is neither array nor pointer

• error: invalid use of flexible array member

Here you wanna make a pointer to the first element of the array

``````uint8_t (*matrix_ptr)[20] = l_matrix;
``````

With typedef, this looks cleaner

``````typedef uint8_t array_of_20_uint8_t[20];
array_of_20_uint8_t *matrix_ptr = l_matrix;
``````

Then you can enjoy life again :)

``````matrix_ptr[0][1] = ...;
``````

Beware of the pointer/array world in C, much confusion is around this.

### Edit

Reviewing some of the other answers here, because the comment fields are too short to do there. Multiple alternatives were proposed, but it wasn't shown how they behave. Here is how they do

``````uint8_t (*matrix_ptr)[][20] = l_matrix;
``````

If you fix the error and add the address-of operator `&` like in the following snippet

``````uint8_t (*matrix_ptr)[][20] = &l_matrix;
``````

Then that one creates a pointer to an incomplete array type of elements of type array of 20 uint8_t. Because the pointer is to an array of arrays, you have to access it with

``````(*matrix_ptr)[0][1] = ...;
``````

And because it's a pointer to an incomplete array, you cannot do as a shortcut

``````matrix_ptr[0][0][1] = ...;
``````

Because indexing requires the element type's size to be known (indexing implies an addition of an integer to the pointer, so it won't work with incomplete types). Note that this only works in `C`, because `T[]` and `T[N]` are compatible types. C++ does not have a concept of compatible types, and so it will reject that code, because `T[]` and `T[10]` are different types.

The following alternative doesn't work at all, because the element type of the array, when you view it as a one-dimensional array, is not `uint8_t`, but `uint8_t[20]`

``````uint8_t *matrix_ptr = l_matrix; // fail
``````

The following is a good alternative

``````uint8_t (*matrix_ptr)[10][20] = &l_matrix;
``````

You access it with

``````(*matrix_ptr)[0][1] = ...;
matrix_ptr[0][0][1] = ...; // also possible now
``````

It has the benefit that it preserves the outer dimension's size. So you can apply sizeof on it

``````sizeof (*matrix_ptr) == sizeof(uint8_t) * 10 * 20
``````

There is one other answer that makes use of the fact that items in an array are contiguously stored

``````uint8_t *matrix_ptr = l_matrix[0];
``````

Now, that formally only allows you to access the elements of the first element of the two dimensional array. That is, the following condition hold

``````matrix_ptr[0] = ...; // valid
matrix_ptr[19] = ...; // valid

matrix_ptr[20] = ...; // undefined behavior
matrix_ptr[10*20-1] = ...; // undefined behavior
``````

You will notice it probably works up to `10*20-1`, but if you throw on alias analysis and other aggressive optimizations, some compiler could make an assumption that may break that code. Having said that, i've never encountered a compiler that fails on it (but then again, i've not used that technique in real code), and even the C FAQ has that technique contained (with a warning about its UB'ness), and if you cannot change the array type, this is a last option to save you :)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download