struct grid {
int width, height;
void *cells[];
};
typedef struct grid grid;
int main(){
enum { width = 2, height = 10 };
grid *g = malloc(sizeof(grid) + width * height * sizeof(void *));
void *(*cells)[10] = &g->cells;
}
My professor taught us about this cool way to allocate a flexible array and then assign a pointer that points to an entire array of pointers
void *(*cells)[10] = &g->cells;
<-- This line
So i tried this method
char *array[10];
char *(*pointer)[2] = &array;
And it just gave me a compiler error
warning: incompatible pointer types initializing
'char *(*)[2]' with an expression of type 'char *(*)[10]'
[-Wincompatible-pointer-types]
char *(*pointer)[2] = &array;
If anyone could explain to me the functionality of a "pointer to an entire array" that would be useful. Thank you
Lets take your correct declaration first:
void *(*cells)[10] = &g->cells;
To understand this, recognize first that cells
is the identifier being declared, and from there follow precedence rules:
(*cells)
says that cells
is a pointer, and the rest of the declaration describes the pointed-to thing. The parentheses are simply to enforce precedence, just like in an arithmetic expression. [10]
applies next, because brackets have higher precendence than unary *
. This says, then, that (*cells)
is an array with 10 elements. void *
out front, which gives the type of each element. And if we look at &g->cells
, it is a pointer to an array of an unspecified number of void *
.
Now consider your code:
char *array[10]; char *(*pointer)[2] = &array;
Following similar procedure, we get that pointer
is declared as a pointer to an array of 2 char *
. So far, so good. Now, what are you trying to assign to it? Why, it's a pointer to an array of 10 char *
. That's a pointer to a different, incompatible type.
In the first case, the initializer's type is a pointer to an "incomplete type" that is compatible with the type to which the pointer points. (It is incomplete because the array length is unspecified; it is compatible because in all other respects it matches the other type.) The pointed-to thing could be an array of the length implicitly asserted by the assignment, and C will treat the pointer as if it were.
In the second case, C can see that the two pointers definitely point to objects of different size, and that therefore the assignment is definitely incorrect. You would need a cast or a change to the type of pointer
to make it accept the initialization.
&array
is the address of an array containing 10 pointers to char
pointer
is a pointer to an array containing 2 pointers to char
2 != 10
, hence the warning.
There's a handy website that helps to understand difficult c decelerations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.