我正在创建一个学校管理系统。当我在添加学生后尝试删除学生时,出现“malloc():损坏的顶部大小”错误。找不到原因。我是初学者,请帮忙
我创建的结构:
typedef struct {
char name[NAME_LENGTH ];
int age;
int roll_no;
char blood_group[BG_LENGTH];
} Student;
typedef struct {
char school_name[NAME_LENGTH ];
int classes;
int *no_of_students;
Student **students;
} School;
添加学生功能
void add_student(School *school, int class_id, int student_id)
{
if(school==NULL)
{
printf("\n INVALID SCHOOL POINTER\n");
return;
}
if (class_id<0 || class_id >= school->classes )
{
printf("\nINVALID_CLASS_INDEX");
return;
}
if (student_id<0 || student_id >= school->no_of_students[class_id] )
{
printf("\nINVALID STUDENT INDEX");
return;
}
int roll_no;
printf("\nEnter roll number: ");
if (scanf("%d", &roll_no) != 1)
{
printf("\nInvalid input. Please enter a number.\n");
clear_input_buffer();
return;
}
load_students_from_bfile(school, class_id, student_id);
for (int i = 0; i < school->no_of_students[class_id]; i++) {
// printf("Checking roll number at index %d: %d\n", i, school->students[class_id][i].roll_no);
if (school->students[class_id][i].roll_no == roll_no) {
printf("Found existing roll number: %d\n", roll_no);
printf("Roll number already exists!\n");
return;
}
}
school->students[class_id][student_id].roll_no = roll_no;
printf("\nEnter student name: ");
scanf(" %[^\n]", school->students[class_id][student_id].name);
printf("\nEnter age: ");
if (scanf("%d", &school->students[class_id][student_id].age) != 1) {
printf("\nInvalid input. Please enter a number.\n");
clear_input_buffer();
return;
}
int bg_choice;
printf("\nChoose your BloodGroup:\n\n1. A+\n2. A-\n3. B+\n4. B-\n5. AB+\n6. AB-\n7. O+\n8. O- \n\nYour Choice: ");
if (scanf("%d", &bg_choice) != 1)
{
printf("\nInvalid input. Please enter a number.\n");
clear_input_buffer();
return;
} char bg[10];
switch (bg_choice)
{
case 1:
strcpy(bg,"A+");
break;
case 2:
strcpy(bg,"A-");
break;
case 3:
strcpy(bg,"B+");
break;
case 4:
strcpy(bg,"B-");
break;
case 5:
strcpy(bg,"AB+");
break;
case 6:
strcpy(bg,"AB-");
break;
case 7:
strcpy(bg,"O+");
break;
case 8:
strcpy(bg,"O-");
break;
default:
printf("\nInvalid Choice.\n");
break;
}
strcpy(school->students[class_id][student_id].blood_group,bg);
printf("You choose blood_group : %s",school->students[class_id][student_id].blood_group);
add_student_to_bfile(school,class_id,student_id);
}
void delete_student(School *school, int class_id, int roll_no)
{
if(school==NULL)
{
printf("\n INVALID SCHOOL POINTER\n");
return;
}
if (class_id<0 || class_id > school->classes )
{
printf("\nINVALID_CLASS_INDEX");
return;
}
if (roll_no<0 )
{
printf("\nINVALID ROLL NUMBER");
return;
}
delete_student_from_bfile(school, class_id, roll_no) ;
}
3.管理_二进制文件.C
void load_from_bfile(School *school)
{
if (school == NULL) {
printf("\n INVALID SCHOOL POINTER");
return;
}
FILE* bfptr=fopen("school.dat","rb");
if(bfptr==NULL)
{
printf("\n not able to open file %s",strerror(errno));
return;
}
int classes;
char school_name[NAME_LENGTH];
fread(&classes, sizeof(int), 1, bfptr);
fread(school_name, sizeof(char), NAME_LENGTH, bfptr);
strncpy(school->school_name, school_name, NAME_LENGTH);
school->classes = classes;
printf("******SCHOOL DETAILS******");
printf("\nSchool Name: %s\n", school->school_name);
printf("\nNumber of Classes: %d\n", classes);
school->no_of_students = (int *)malloc(school->classes * sizeof(int));
school->students = (Student **)malloc(school->classes * sizeof(Student *));
for (int i = 0; i < classes; i++)
{
school->students[i] = (Student *)malloc(school->no_of_students[i] * sizeof(Student));
int num_students;
fread(&num_students, sizeof(int), 1, bfptr);
school->no_of_students[i] = num_students;
printf("\nClass %d - Number of Students: %d\n", i + 1, num_students);
}
fclose(bfptr);
}
void add_student_to_bfile(School *school, int class_id, int student_id)
{
if(school==NULL)
{
printf("\n INVALID SCHOOL POINTER");
return;
}
if (class_id<0 || class_id >= school->classes )
{
printf("\nINVALID_CLASS_INDEX");
return;
}
if (student_id<0 || student_id >=school->no_of_students[class_id] )
{
printf("\nINVALID STUDENT INDEX");
return;
}
char filename[20];
sprintf(filename, "%d.bin", class_id+1);
FILE *bfptr = fopen(filename, "ab");
if (bfptr == NULL)
{
printf("\nUnable to open file %s: %s\n", filename, strerror(errno));
return;
}
fwrite(&school->students[class_id][student_id], sizeof(Student), 1, bfptr);
fclose(bfptr);
printf("\nStudent details added successfully.\n");
}
void delete_student_from_bfile(School *school, int class_id, int target_rollno)
{
if(school==NULL)
{
printf("\n INVALID POINTER");
return;
}
if (class_id > school->classes) {
printf("\nInvalid class index");
return;
}
char filename[20];
sprintf(filename, "%d.bin", class_id);
FILE *bfptr = fopen(filename, "rb+");
if (bfptr == NULL) {
printf("\nUnable to open file %s: %s\n", filename, strerror(errno));
return;
}
char temp_filename[20];
sprintf(temp_filename, "%d.tmp", class_id);
FILE *temp_bfptr = fopen(temp_filename, "wb+");
if (temp_bfptr == NULL) {
printf("\nUnable to create temporary file %s: %s\n", temp_filename, strerror(errno));
fclose(bfptr);
return;
}
Student student;
int found = 0;
int i=0;
while (fread(&student, sizeof(Student), 1, bfptr) == 1) {
i++;
if (student.roll_no == target_rollno) {
found = 1;
printf("\nStudent with Roll No %d found and deleted.\n", target_rollno);
for (int j = i; j < school->no_of_students[class_id] - 1; j++) {
school->students[class_id][j] = school->students[class_id][j + 1];
}
school->no_of_students[class_id]--;
} else {
fwrite(&student, sizeof(Student), 1, temp_bfptr);
}
}
if (!found) {
printf("\nStudent with Roll No %d not found.\n", target_rollno);
}
fclose(bfptr);
fclose(temp_bfptr);
remove(filename);
rename(temp_filename, filename);
}
输出: 终端输出显示错误
在我的代码中,输入是使用结构获取的,然后将它们保存到二进制文件中,学校记录有单独的文件,每个班级都有单独的文件。
需要删除该错误并更正我的代码
在函数load_from_bfile中:
for (int i = 0; i < classes; i++)
{
school->students[i] = (Student *)malloc(school->no_of_students[i] * sizeof(Student));
int num_students;
fread(&num_students, sizeof(int), 1, bfptr);
school->no_of_students[i] = num_students;
printf("\nClass %d - Number of Students: %d\n", i + 1, num_students);
}
malloc
调用使用school->no_of_students[i]
的值。但是,该值仅在几行之后设置。从使用的角度来看,它还没有任何价值。