Вы усложняете себе задачу, пытаясь использовать нотацию указателя, а не нотацию индекса массива. Например, ваше распределение students
в порядке, но смотрите Разыгрывает ли я результат malloc? .
Когда вы начинаете использовать студентов, тогда как (students + i)->roll_no = i + 1;
технически в порядке,это немного более читабельно, как: students[i].roll_no = i + 1;
. [..]
действует как разыменование. Ваше распределение каждого отдельного студента ptr_mark
будет тогда:
students[i].ptr_marks = malloc (sizeof(int) * marks);
assert (students[i].ptr_marks);
( примечание: подтвердите каждое распределение)
Остальные - просто уборка ив соответствии с использованием понятия индекса массива в students[]...
и обеспечении проверки каждого ввода , например,
for (int j = 0 ; j < marks ; j++) {
printf ("Enter Mark for Subject %d: ", j+1);
if (scanf ("%d", &students[i].ptr_marks[j]) != 1)
return 1;
}
Затем можно освободить все выделенные блоки памяти с помощью:
for (int i = 0; i < num_students; i++)
free (students[i].ptr_marks); /* free storage for ptr_marks */
free(students); /* free pointers */
В целом, вы можете сделать:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define debugging
struct Student {
int age;
int roll_no;
int* ptr_marks;
};
int main (void) {
// total number of students
int num_students;
printf("Enter # of Students: ");
if (scanf("%d",&num_students) != 1)
return 1;
// structure array definition
struct Student *students;
students = malloc (num_students * sizeof(struct Student));
assert(students != NULL);
int marks;
for (int i = 0 ; i < num_students ; i ++) {
students[i].roll_no = i + 1;
students[i].age = i + 10;
printf("Enter #'s of Subjects for Student %d: ",i);
if (scanf("%d", &marks) != 1)
return 1;
// allocating memory for marks obtained by each student
students[i].ptr_marks = malloc (sizeof(int) * marks);
assert (students[i].ptr_marks);
for (int j = 0 ; j < marks ; j++) {
printf ("Enter Mark for Subject %d: ", j+1);
if (scanf ("%d", &students[i].ptr_marks[j]) != 1)
return 1;
}
}
#ifdef debugging
for (int j = 0 ; j < num_students ; j ++) {
printf("The roll # of student %d are %d \n", j+1, (students+j)->roll_no);
}
#endif
for (int i = 0; i < num_students; i++)
free (students[i].ptr_marks);
free(students);
return 0;
}
Пример использования / Вывод
Упражнения с разными входами приведут к:
$ ./bin/struct_ptr_alloc
Enter # of Students: 2
Enter #'s of Subjects for Student 0: 3
Enter Mark for Subject 1: 90
Enter Mark for Subject 2: 91
Enter Mark for Subject 3: 94
Enter #'s of Subjects for Student 1: 3
Enter Mark for Subject 1: 87
Enter Mark for Subject 2: 72
Enter Mark for Subject 3: 93
The roll # of student 1 are 1
The roll # of student 2 are 2
Использование памяти / проверка ошибок
В любом написанном вами коде, который динамически распределяет память, у вас есть 2 обязанности относительно любого блокавыделенной памяти: (1) всегда сохраняйте указатель на начальный адрес для блока памяти, поэтому (2) он может быть освобожден , когда он больше не нужен.
Обязательно используйте программу проверки ошибок памяти, чтобы убедиться, что вы непопытаться получить доступ к памяти или выполнить запись за пределами / за пределами выделенного блока, попытаться прочитать или основать условный переход на неинициализированном значении и, наконец, подтвердить, что вы освобождаете всю выделенную память.
Для Linux valgrind
- нормальный выбор. Для каждой платформы есть похожие проверки памяти. Все они просты в использовании, просто запустите вашу программу через нее.
$ valgrind ./bin/struct_ptr_alloc
==5051== Memcheck, a memory error detector
==5051== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5051== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==5051== Command: ./bin/struct_ptr_alloc
==5051==
Enter # of Students: 2
Enter #'s of Subjects for Student 0: 2
Enter Mark for Subject 1: 99
Enter Mark for Subject 2: 100
Enter #'s of Subjects for Student 1: 2
Enter Mark for Subject 1: 89
Enter Mark for Subject 2: 92
The roll # of student 1 are 1
The roll # of student 2 are 2
==5051==
==5051== HEAP SUMMARY:
==5051== in use at exit: 0 bytes in 0 blocks
==5051== total heap usage: 5 allocs, 5 frees, 2,096 bytes allocated
==5051==
==5051== All heap blocks were freed -- no leaks are possible
==5051==
==5051== For counts of detected and suppressed errors, rerun with: -v
==5051== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Всегда подтверждайте, что вы освободили всю выделенную память и что ошибок памяти нет.
Посмотрите вещии дайте мне знать, если у вас есть дополнительные вопросы.