Hi mọi người,
Mình có 1 bài tập như sau:
Mình tạo 3 struct:
Còn đây là source code:
#pragma once
#include <iostream>
#include <string>
#include <algorithm>
#include <fstream>
typedef struct subject SJ;
struct subject
{
std::string subject_name; // tên môn học
double mark; // điểm của môn học
};
std::istream& operator >> (std::istream &, SJ *);
std::istream& operator >> (std::istream &, SJ &);
std::ostream& operator << (std::ostream &, SJ *);
std::ostream& operator << (std::ostream &, SJ &);
#include "SubJect.h"
std::istream& operator >> (std::istream &is, SJ *s)
{
std::cout << "Nhap ten mon hoc: ";
while (getchar() != '\n' && getchar() != EOF) {}
std::getline(is, s->subject_name);
std::cout << "Nhap diem mon hoc: ";
is >> s->mark;
return is;
}
std::istream& operator >> (std::istream &is, SJ &s)
{
std::cout << "Nhap ten mon hoc: ";
while (getchar() != '\n' && getchar() != EOF) {}
std::getline(is, s.subject_name);
std::cout << "Nhap diem mon hoc: ";
is >> s.mark;
return is;
}
std::ostream& operator << (std::ostream &os, SJ *s)
{
os << "Ten mon hoc: " << s->subject_name << std::endl;
os << "Diem mon hoc: " << s->mark << std::endl;
return os;
}
std::ostream& operator << (std::ostream &os, SJ &s)
{
os << "Ten mon hoc: " << s.subject_name << std::endl;
os << "Diem mon hoc: " << s.mark << std::endl;
return os;
}
#pragma once
#include "SubJect.h";
typedef struct student STD;
struct student
{
std::string name;
std::string code;
int n_subjects;
SJ *sjs; // mảng sjs kiểu SJ để lưu thông tin nhiều môn học
};
std::istream& operator >> (std::istream &, STD *);
std::istream& operator >> (std::istream &, STD &);
std::ostream& operator << (std::ostream &, STD *);
std::ostream& operator << (std::ostream &, STD &);
#include "StuDent.h";
std::istream& operator >> (std::istream &is, STD *s)
{
std::cout << "\nNhap ho va ten: ";
while (getchar() != '\n' && getchar() != EOF) {}
std::getline(is, s->name);
std::cout << "\nNhap ma so: ";
is >> s->code;
std::cout << "\nNhap so luong mon hoc: ";
is >> s->n_subjects;
std::cout << "\n\t---------- Nhap danh sach mon hoc ----------\t" << std::endl;
s->sjs = new SJ[s->n_subjects];
for (int i = 0; i < s->n_subjects; ++i)
{
std::cout << "\nNhap thong tin mon " << i + 1 << ":\n";
is >> s->sjs[i];
}
return is;
}
std::istream& operator >> (std::istream &is, STD &s)
{
std::cout << "\nNhap ho va ten: ";
while (getchar() != '\n' && getchar() != EOF) {}
std::getline(is, s.name);
std::cout << "\nNhap ma so: ";
is >> s.code;
std::cout << "\nNhap so luong mon hoc: ";
is >> s.n_subjects;
std::cout << "\n\t---------- Nhap danh sach mon hoc ----------\t" << std::endl;
s.sjs = new SJ[s.n_subjects];
for (int i = 0; i < s.n_subjects; ++i)
{
std::cout << "\nNhap thong tin mon " << i + 1 << ":\n";
is >> s.sjs[i];
}
return is;
}
std::ostream& operator << (std::ostream &os, STD *s)
{
os << "\nHo va ten: " << s->name << std::endl;
os << "\nMa so: " << s->code << std::endl;
os << "\n\t---------- Danh sach mon hoc ----------\t\n";
for (int i = 0; i < s->n_subjects; ++i)
{
os << "\nMon " << i + 1 << ":\n";
os << s->sjs[i];
}
return os;
}
std::ostream& operator << (std::ostream &os, STD &s)
{
os << "\nHo va ten: " << s.name << std::endl;
os << "\nMa so: " << s.code << std::endl;
os << "\n\t---------- Danh sach mon hoc ----------\t\n";
for (int i = 0; i < s.n_subjects; ++i)
{
os << "\nMon " << i + 1 << ":\n";
os << s.sjs[i];
}
return os;
}
#pragma once
#include "StuDent.h";
typedef struct grade GRD;
struct grade
{
int n_students;
STD *students;
};
std::istream& operator >> (std::istream &, GRD *);
std::istream& operator >> (std::istream &, GRD &);
std::ostream& operator << (std::ostream &, GRD *);
std::ostream& operator << (std::ostream &, GRD &);
#include "Grade.h"
std::istream& operator >> (std::istream &is, GRD *g)
{
std::cout << "Nhap so luong hoc sinh: ";
is >> g->n_students;
g->students = new STD[g->n_students];
for (int i = 0; i < g->n_students; ++i)
{
std::cout << "\n\t------------ NHAP THONG TIN HOC SINH " << i + 1 << " ------------\t\n";
is >> g->students[i];
}
return is;
}
std::istream& operator >> (std::istream &is, GRD &g)
{
std::cout << "Nhap so luong hoc sinh: ";
is >> g.n_students;
g.students = new STD[g.n_students];
for (int i = 0; i < g.n_students; ++i)
{
std::cout << "\n\t------------ NHAP THONG TIN HOC SINH " << i + 1 << " ------------\t\n";
is >> g.students[i];
}
return is;
}
std::ostream& operator << (std::ostream &os, GRD *g)
{
for (int i = 0; i < g->n_students; ++i)
{
os << "\n\t------------ THONG TIN HOC SINH " << i + 1 << " ------------\t\n";
os << g->students[i];
}
return os;
}
std::ostream& operator << (std::ostream &os, GRD &g)
{
for (int i = 0; i < g.n_students; ++i)
{
os << "\n\t------------ THONG TIN HOC SINH " << i + 1 << " ------------\t\n";
os << g.students[i];
}
return os;
}
#include "Grade.h";
void WriteFile(std::fstream &, GRD *); // đọc thông tin từ struct vào file nhị phân
void SortList(GRD *); // sắp xếp danh sách lớp học theo thứ tự Alphabet
std::string CutStrName(std::string); // lấy ra tên chính trong 1 tên
void ReadFile(std::fstream &, GRD *); // đọc thông tin từ file nhị phân vào biến struct
bool Bigger(double , double ); // con trỏ hàm
bool Smaller(double , double ); // con trỏ hàm
double AverageMark(GRD *, int ); // trả về điểm trung bình của 1 học sinh có chỉ số là tham số index của hàm
void SortList_AverageMark(GRD *, bool(*)(double, double)); // sắp xếp danh sách lớp tăng/giảm theo điểm trung bình
int PrntInf_BestAvrgMark(GRD *g, bool(*)(double, double)); // xuất thông tin của học sinh có điểm trung bình cao/thấp nhất
void WriteFile(std::fstream &FileOut, GRD *g)
{
std::cin.ignore();
FileOut.write((char *)g, sizeof(GRD));
}
std::string CutStrName(std::string str) // This function gets the last name of a name
{
int length = str.length();
std::string string;
for (int i = length - 1; i >= 0; --i)
{
if (str.at(i) != ' ')
string.push_back(str.at(i));
else
break;
}
std::reverse(std::begin(string), std::end(string));
return string;
}
void SortList(GRD *g)
{
for (int i = 0; i < g->n_students - 1; ++i)
{
for (int j = i + 1; j < g->n_students; ++j)
{
if (CutStrName(g->students[i].name) > CutStrName(g->students[j].name))
std::swap(g->students[i], g->students[j]);
}
}
}
void ReadFile(std::fstream &FileIn, GRD *_g)
{
FileIn.read((char *)_g, sizeof(GRD));
}
bool Bigger(double a, double b)
{
return a > b;
}
bool Smaller(double a, double b)
{
return a < b;
}
double AverageMark(GRD *g, int index)
{
double sum = 0;
double count = 0;
for (int i = 0; i < g->students[index].n_subjects; ++i)
{
sum += g->students[index].sjs[i].mark;
++count;
}
return sum / count;
}
void SortList_AverageMark(GRD *g, bool(*ptr)(double, double))
{
for (int i = 0; i < g->n_students - 1; ++i)
{
for (int j = i + 1; j < g->n_students; ++j)
{
if (ptr(AverageMark(g, i), AverageMark(g, j)))
std::swap(g->students[i], g->students[j]);
}
}
}
int PrntInf_BestAvrgMark(GRD *g, bool(*ptr)(double, double))
{
double MaxMin = g->students[0].sjs[0].mark;
int index = 0;
for (int i = 0; i < g->n_students; ++i)
{
if (ptr(AverageMark(g, i), MaxMin))
index = i;
}
return index;
}
int main()
{
GRD *g = new GRD;
std::cin >> g;
//std::cout << g;
SortList(g);
std::fstream FileOut("DanhSachLopHoc.doc", std::ios_base::out | std::ios_base::binary);
WriteFile(FileOut, g);
FileOut.close();
GRD *_g = new GRD;
FileOut.open("DanhSachLopHoc.doc", std::ios::in | std::ios::binary);
ReadFile(FileOut, _g);
FileOut.close();
std::cout << _g;
std::cout << "\n\t DANH SACH LOP HOC SAU KHI SAP XEP THEO YEU CAU \t\n";
SortList_AverageMark(_g, Smaller);
std::cout << _g;
std::cout << "\n\t THONG TIN SINH VIEN CO DTB THEO YEU CAU \t\n";
std::cout << _g->students[PrntInf_BestAvrgMark(g, Bigger)] << std::endl;
/*
delete[] _g->students->sjs;
delete[] _g->students;
delete _g;
delete[] g->students->sjs;
delete[] g->students;
delete g;
*/
system("pause");
return 0;
}
Vấn đề là ở file souce.cpp, khi mình giải phóng con trỏ ở dưới thì nó báo lỗi, cụ thể là ở thằng delete[] g->students->sjs; ấy:

Mọi người ai biết lỗi này giúp mình nhé. Xin cảm ơn !
P/S: Tuy source code có hơi lằng nhằng và dài dòng nhưng mình đã chú thích hết cỡ rồi. Mong mọi người chịu khó nhé 
(không biết có hợp lý không =]])
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?