2016-02-16 9 views
2

Можно использовать designated initializers, как показано ниже (для «билли») без проблем, но когда тот же подход к инициализации используется в динамической памяти, вещи будут разбиваться во время компиляции.Использование назначенных инициализаторов с кучей

Каковы ограничения на использование назначенных инициализаторов?

Помимо , где (т. Е. Адрес), который мы пишем, что отличает эти две инициализации? Почему мы не можем использовать назначенные инициализаторы с динамической памятью?

struct student{ 
    char *name; 
    int age; 
}; 


void print_student(struct student* st){ 
    printf("Student: %s is %d years old\n", st->name, st->age); 
} 


int main(void) {  
    srand(time(NULL)); 
    struct student *molly_ptr = malloc(sizeof(struct student)); 

    struct student billy = { 
          .name = "billy", 
          .age = rand()%30 
          }; 

    *molly_ptr = { 
        .name = "molly", 
        .age = 25 
       }; 

    //molly_ptr->name = "molly"; 
    //molly_ptr->age = 25; 

    print_student(&billy); 
    print_student(molly_ptr); 


    return 0; 
} 

error: expected expression before '{' token 
    *molly_ptr = { 
      ^
+2

Инициализация и назначение - это две разные вещи. Вторая вещь, которую вы пытаетесь сделать, - это назначение. Этот синтаксис недоступен для AFAIK. (Не связано с кучей/стек.) – Mat

+0

'char * name' предпочтительно следует объявлять как' const char * name'. – Lundin

+0

@ Lundin, код был создан только для этого вопроса. Существует также технически утечка памяти. – sherrellbc

ответ

4

Используйте соединение буквального:

*molly_ptr = (struct student){ .name = "molly", .age = 25 }; 

Это почти идентично:

struct student temp = { .name = "molly", .age = 25 }; 
*molly_ptr = temp; 
+0

Очень интересно, хотя источник [this] (https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html) указывает, что данные, на которые указывает, теперь находятся в стеке. Это вызовет утечку памяти, учитывая код выше. Я не знал об этом синтаксисе. – sherrellbc

+1

@sherrellbc Неверный. molly_ptr все еще указывает на выделенную память. Вся структура копируется в эту память. Это ясно видно из моего второго примера. – 2501

+0

Это то, что мне очень интересно, и я не знаю, кто из вас прав. Если это был код C++, я мог видеть, что он копируется, но поскольку это C, я думаю, что указатель просто указывает на что-то в стеке. Есть ли что-то, что может прояснить это? Вероятно, это будет хорошим вопросом. – callyalater

3

Вы должны написать:

*molly_ptr = (struct student){ 
           .name = "molly", 
           .age = 25 
          };