I'm trying to assign a compound literal to a variable, but it seems not to work, see:
int *p[] = (int *[]) {{1,2,3},{4,5,6}};
I got a error in gcc.
but if I write only this:
int p[] = (int []) {1,2,3,4,5,6};
Then it's okay.
But is not what I want.
I don't understand why the error occurrs, because if I initialize it like a array, or use it with a pointer of arrays of chars, its okay, see:
int *p[] = (int *[]) {{1,2,3},{4,5,6}}; //I got a error int p[][3] = {{1,2,3},{4,5,6}}; //it's okay char *p[] = (char *[]) {"one", "two"...}; // it's okay!
Note I don't understand why I got an error in the first one, and please I can't, or I don't want to write like the second form because it's needs to be a compound literals, and I don't want to say how big is the array to the compiler. I want something like the second one, but for int values.
Thanks in advance.
First, the casts are redundant in all of your examples and can be removed. Secondly, you are using the syntax for initializing a multidimensional array, and that requires the second dimension the be defined in order to allocate a sequential block of memory. Instead, try one of the two approaches below:
Multidimensional array:
int p[][3] = {{1,2,3},{4,5,6}};
Array of pointers to one dimensional arrays:
int p1[] = {1,2,3}; int p2[] = {4,5,6}; int *p[] = {p1,p2};
The latter method has the advantage of allowing for sub-arrays of varying length. Whereas, the former method ensures that the memory is laid out contiguously.
Another approach that I highly recommend that you do NOT use is to encode the integers in string literals. This is a non-portable hack. Also, the data in string literals is supposed to be constant. Do your arrays need to be mutable?
int *p[] = (int *[]) { "\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00", "\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00" };
That example might work on a 32-bit little-endian machine, but I'm typing this from an iPad and cannot verify it at the moment. Again, please don't use that; I feel dirty for even bringing it up.
The casting method you discovered also appears to work with a pointer to a pointer. That can be indexed like a multidimensional array as well.
int **p = (int *[]) { (int[]) {1,2,3}, (int[]) {4,5,6} };
First understand that "Arrays are not pointers".
int p[] = (int []) {1,2,3,4,5,6};
In the above case p
is an array of integers. Copying the elements {1,2,3,4,5,6}
to p
. Typecasting is not necessary here and both the rvalue
and lvalue
types match which is an integer array and so no error.
int *p[] = (int *[]) {{1,2,3},{4,5,6}};
"Note I don't understand why I got a error in the first one,.."
In the above case, p
an array of integer pointers. But the {{1,2,3},{4,5,6}}
is a two dimensional array ( i.e., [][] ) and cannot be type casted to array of pointers. You need to initialize as -
int p[][3] = { {1,2,3},{4,5,6} }; // ^^ First index of array is optional because with each column having 3 elements // it is obvious that array has two rows which compiler can figure out.
But why did this statement compile ?
char *p[] = {"one", "two"...};
String literals are different from integer literals. In this case also, p
is an array of character pointers. When actually said "one"
, it can either be copied to an array or point to its location considering it as read only.
char cpy[] = "one" ; cpy[0] = 't' ; // Not a problem char *readOnly = "one" ; readOnly[0] = 't' ; // Error because of copy of it is not made but pointing // to a read only location.
With string literals, either of the above case is possible. So, that is the reason the statement compiled. But -
char *p[] = {"one", "two"...}; // All the string literals are stored in // read only locations and at each of the array index // stores the starting index of each string literal.
I don't want to say how big is the array to the compiler.
Dynamically allocating the memory using malloc
is the solution.
Hope it helps !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With