I have the following code:
typedef struct Test {
long mem[1000];
} Test;
extern Test *test;
int main() {
Test *test = (Test *)malloc(sizeof(Test));
test->mem[0] = 1;
test->mem[1] = 2;
test->mem[2] = 3;
test->mem[3] = 4;
test->mem[4] = 5;
test->mem[5] = 6;
return 0;
}
It's working OK, but I want to change the initalization of the mem array to be in that way:
test->mem = {1,2,3,4,5,6};
But the gcc giving me this error:
error: expected expression before '{' token test->mem = {1,2,3,4,5,6}; With arrow pointing to the left open braces.
What it can be?
Thanks!
EDIT: I also try this code:
long mem[1000] = {1,2,3,4,5,6};
test->mem = mem;
And I'm getting this error from gcc:
error: incompatible types when assigning to type 'long int[1048576]' from type 'long int *' test->mem = mem;
I'm not allow to use any C functions.
The syntax something = { initial values }
is allowed only in initializations, where an object is defined, such as:
long mem[1000] = { 1, 2, 3, 4, 5, 6 };
An expression such as x = value
is an assignment and cannot use the syntax for initializations.
One alternative is to create a temporary object, which you initialize, and then copy the contents of that temporary object into the target:
static const long temporary[] = { 1, 2, 3, 4, 5, 6 };
memcpy(test->mem, temporary, sizeof temporary);
Regarding the edit:
Arrays may not be assigned; x = value
is not valid if x
is an array. However, structures may be assigned, so another alternative is to create a structure as a temporary object, initialize it, and assign it:
// (After the malloc is successful.)
static const Test temporary = { { 1, 2, 3, 4, 5, 6 } };
*test = temporary;
Note, however, that this code does something the prior code does not. The prior example I showed merely copies six elements into the array. This code creates a temporary object of type Test
, which contains 1000 elements, most of them zero, and it copies all of those elements into *test
. Even if the compiler optimizes this and uses some code to clear *test
rather than actually copying zeroes stored in memory, it takes longer than just copying six elements. So, if you just want a few elements initialized and do not care about the rest, use the former code. If you want all the elements initialized (most to zero), you can use the latter code. (Even so, I would consider alternatives, like using calloc
instead of malloc
.)
Arrays are not pointers (but arrays decay to pointers, see this), and you cannot assign arrays (only initialize them, or assign struct
-s containing them). You could copy the array, e.g.
Test *test = (Test *)malloc(sizeof(Test));
if (!test) { perror("malloc"); exit(EXIT_FAILURE); };
static const int arr[] = {1,2,3,4,5,6};
memcpy (test->mem, arr, sizeof(arr));
BTW, you could copy without using memcpy
by coding your loop for (int i=0; i<6; i++) test->mem[i] = arr[i];
....
This leaves 9994 integers in test
uninitialized; you might want to clear them:
memset (test->mem+6, 0, 9994*sizeof(int));
or use another for
loop.
You could also define your initialized structure, e.g.
Test mystruct = {0, 2, 4, 6, 8};
then assign it, e.g.
*test = mystruct;
but you cannot assign arrays! Even
// wrong code, won't compile
int ta[4] = { 0, 1, 2, 3}; // initialization, not assignment
int tb[4] = { 2, 4, 6, 8}; // ditto
int *tp = &ta;
ta = tb; // wrong!
tb = tp; // also wrong
won't compile.
FWIW, C++11 has std::array to help about that.
The §6.5.16.1 Simple assignment section of the C11 standard (see n1570 draft page 102) lists a set of constraints regarding assignment, and array assignment don't fit there. Hence it is forbidden. A rule of thumb is that only scalars (that includes pointers and numerical l-values) or struct
-s can appear on the left hand side of an assignment (or be return
-ed from a function).
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