简体   繁体   中英

How to initialize a constant array of struct in another dynamically allocated struct

Here is my problem, I try to initialize constant values from a struct, for simple values I do like this: *(int*)&myStruct->myValue = 1; and it works very well but for the array I would have liked to use a similar method more than a 'memcpy' so I did like this:

*(MyOtherStruct*)&myStruct->myArrayOfStructs = {
    otherStruct1,  otherStruct2,
    otherStruct3,    otherStruct4
};

But I get this: error: expected expression before '{' token

And I tried a lot of things but either it was totally buggy, or I had other error messages, I can't find the expression that the compiler wants and that works correctly...

Afterwards maybe the use of 'memcpy' is "obligated" but I will find it better without for my code if possible.

Thanks in advance !

EDIT: Here is an abstract but "working" example of what I want to do.

#include <stdlib.h>

typedef struct {
    int r, g, b, a;
} Color;

typedef struct {
    const int value;
    const Color color[4];
} structExample;

int main(void)
{
    Color colorWhite = { 0, 0, 0, 255 };
    Color colorBlack = { 255, 255, 255, 255 };
    Color colorRed   = { 255, 0, 0, 255 };
    Color colorBlue  = { 0, 0, 255, 255 };

    structExample* myStruct = malloc(sizeof(structExample));

    *(int*)&myStruct->value = 1;

    *(Color*)&myStruct->color = {
        colorWhite,  colorBlack,
        colorRed,    colorBlue
    };

    return 0;
}

You cant assign the arrays. You need to do this manually

myStruct->myArrayOfStructs[0] = otherStruct1;
myStruct->myArrayOfStructs[1] = otherStruct2;
myStruct->myArrayOfStructs[2] = otherStruct3;
myStruct->myArrayOfStructs[3] = otherStruct4;

You cannot assign an array, nor multiple elements of an array with one assignment. You can assign the elements of the array, for which you ought to do the casting correctly:

  • myStruct->color is an array of 4 Color . Taking its address yields a Color (*)4 . Casting that to Color * leads to technical violations of rules required for the behavior to be define by the C standard.
  • Your goal is to remove const from the element. So simply take the address of an element instead of taking the address of the array:
* (Color *) &myStruct->color[0] = colorWhite;
* (Color *) &myStruct->color[1] = colorBlack;
* (Color *) &myStruct->color[2] = colorRed;
* (Color *) &myStruct->color[3] = colorBlue;

However, this casting away of const makes it irksome to avoid violating rules of the C standard regarding defined behavior. A better approach is:

  • Remove the const from the member declarations in structExample .
  • Allocate memory and initialize the structure with no const involved.
  • Assign the pointer to the memory to a new pointer that does have const .

When you do this, you can also use a compound literal to initialize the structure (even though it contains an array). Here is an example:

#include <stdlib.h>


typedef struct
{
    int r, g, b, a;
} Color;

typedef struct
{
    int value;
    Color color[4];
} structExample;


int main(void)
{
    Color colorWhite = {   0,   0,   0, 255 };
    Color colorBlack = { 255, 255, 255, 255 };
    Color colorRed   = { 255,   0,   0, 255 };
    Color colorBlue  = {   0,   0, 255, 255 };

    //  Start with pointer to non-const object.
    structExample *myStruct = malloc(sizeof *myStruct);

    //  Assign initial value.
    *myStruct = 
        (structExample) { 1, { colorWhite, colorBlack, colorRed, colorBlue } };

    //  Convert to pointer to const object.
    const structExample *myStructConst = myStruct;

    //  Use pointer-to-const for further work.
    extern void foo(const structExample *);
    foo(myStructConst);
        /*  Inside foo, only the pointer-to-const is seen, so it will get a
            diagnostic message if it attempts to modify the structure without
            using an explicit cast.  foo does not see the original myStruct
            pointer.
        */

    //  Use the original pointer to free.
    free(myStruct);
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM