2015-01-26 2 views
2

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

struct Params { 
    int a; 
    int b; 
}; 

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

settings член сопз как намек на то, что он не должен быть изменен один раз в 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?

+0

Это не имеет смысла чтобы иметь 'const' копию структуры, имеет смысл иметь указатель' const' экземпляра структуры. –

+1

должен 'if (a)' быть 'if (n)'? –

+2

Объявление const в C просит компилятор не позволять вам назначать объект через этот псевдоним в области декларации. Это не означает, что объект является константой. – philipxy

ответ

0

память выделяется (и, следовательно, не является постоянной), так что это законно, чтобы бросить 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; 
} 
+0

Изменено 'if (a)' to 'if (n)', похожее на опечатку. – mafso

+2

Почему вы используете '(void *)' вместо '(struct Params *)'? – mch

+1

@mch, либо будет работать, и я не думаю, что любой из них лучше. 'void *' короче. – mafso

0

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

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; 
}