C - malloc для указателя на структуру - PullRequest
0 голосов
/ 24 июня 2018

Мой код работает, но я не выяснил, как malloc выделяет память для указателя на структуру в C. И в моем коде я не выделил весь размер моей структуры для моего указателя, а только размер его члена, это хорошо или плохо? И если это плохо, что я должен сделать, чтобы оптимизировать мой код.

Вот мой код:

struct Student
{
    char name[25];
    float math, physic;
    char rank;
};



void studentManagement(void)
{
struct  Student *s;
int n,i=1;
float ave;

printf("Number of student = ");
scanf("%d", &n);
getchar();

    while(i<=n)
    {
         s = malloc(25*sizeof(char));

         printf("Enter student name: ");
         fgets(s->name,25,stdin);             
         free(s);

         s = malloc(5*sizeof(float));

         printf("Physics grade = ");
         scanf("%f", &s->physic);
         printf("Math grade = ");
         scanf("%f", &s->math);

         getchar();

         ave = ((s->math )+ (s->physic)) / 2;

         if(ave<5) 
             printf("Rank = D\n");
         if(ave >= 5 && ave <= 7) 
             printf("Rank = C\n");
         if(ave >= 7 && ave <= 8) 
             printf("Rank = B\n");
         if(ave > 8) 
             printf("Rank = A\n");

         free(s);
         i++;
  }
}

1 Ответ

0 голосов
/ 24 июня 2018

В s = malloc(25*sizeof(char)); вы выделяете пространство и устанавливаете s, чтобы указать на это пространство.s - указатель на struct Student.Так что s должно указывать на достаточно места для struct Student.Таким образом, правильное выделение:это остается правильным, если код позже изменяется, так что s указывает на объект другого типа.

Сразу после получения имени у вас есть free(s);.Это неверноВы должны освобождать память только тогда, когда вы закончили с ней.Но вы все еще хотите использовать объект, на который указывает s, поэтому слишком рано освобождать s.

Аналогично, вам не нужно использовать s = malloc(5*sizeof(float));.Оператор s = malloc(sizeof *s); будет (в случае успеха) выделять достаточно памяти для всех из struct Student.Вы выделяете целую структуру, используете ее, а затем освобождаете.Вы не выделяете фрагменты структуры.

После того, как этот фрагмент кода работает правильно, вы должны подумать о том, почему вы выделяете пространство для struct Student, а затем вскоре освободите его.Если вы просто хотите работать с struct Student для одной итерации цикла, вы можете сделать это, объявив struct Student s; вместо выделения памяти и указания на нее.Задание, над которым вы работаете, может потребовать построения массива struct Student, и в этом случае вам придется подумать о том, как распределить память для всего массива и сколько элементов вам понадобится в массиве.

...