Правильный способ инициализации элемента const динамически выделенной структуры


У меня есть эти 2 структуры:

struct Params {
    int a;
    int b;
};

struct Foo {
    const struct Params settings;
    int state;
};

Элемент settings является const как намек на то, что он не должен быть изменен после того, как struct Foo был создан и инициализирован.

И я хочу динамически выделить эту структуру, например

struct Foo * new_foo(void)
{
     struct Foo *n = malloc(sizeof *n);
     if (n) {
         n->settings.a = SETTING_A;
         n->settings.b = SETTING_B;
         ...
      }

      return n;
}

Теперь это не будет компилироваться из-за настроек const. Что такое правильный путь к инициализировать такую структуру таким образом? Или лучше не объявлять элемент settings как const?

2 2

2 ответа:

Память выделена (и, следовательно, не постоянна), поэтому законно отбросить const:

struct Foo * new_foo(void)
{
    struct Foo *n = malloc(sizeof *n);
    if (n) {
        struct Params *s = (void *)&n->settings;
        s->a = SETTING_A;
        s->b = SETTING_B;
    }
    return n;
}

Вот один из способов сделать это:

struct Foo *new_foo(void)
{
    static struct Foo foo =
    {
        .settings =
        {
            .a = SETTING_A,
            .b = SETTING_B
        },
        .state = ...
    };

    struct Foo *n = malloc(sizeof *n);
    memcpy(n, &foo, sizeof *n);

    return n;
}

Вот еще один способ сделать это:

struct Foo *new_foo(void)
{
    static struct Params settings =
    {
        .a = SETTING_A,
        .b = SETTING_B
    };

    struct Foo *n = malloc(sizeof *n);
    memcpy((struct Params*)&n->settings, &settings, sizeof settings);
    n->state = ...;

    return n;
}