Lỗi Exception Thrown

Chào mọi người! Em đang code 1 bài bị báo lỗi Exception thrown trong hàm SapXep(). Em đặt breakpoint debug dòng if ((SV[i]->DTB()) < (SV[j]->DTB())) thì báo là SV[i]SV[j] có giá trị NULL. Mọi người có thể giúp em lỗi này được không ạ? Code của em làm được:

#include <iostream>
#include <string>
#include <vector>

using namespace std;
class SinhVien {
protected:
	int maso;
	string hoten;
	string he;
	float LTC;
	float dtb;
public:
	SinhVien() {

	}

	virtual void Nhap() {
		cout << "\nNhap ma so sinh vien: ";
		cin >> maso;
		cout << "\nNhap ho va ten sinh vien: ";
		cin.ignore();
		getline(cin, hoten);
		cout << "\nNhap he dao tao: ";
		//cin.ignore();
		getline(cin, he);
		cout << "\nNhap diem lap trinh C: ";
		cin >> LTC;
	}

	virtual void Xuat() {
		cout << "\nMa so sinh vien: " << maso;
		cout << "\nHo va ten: " << hoten;
		cout << "\nHe: " << he;
		cout << "\nDiem lap trinh C: " << LTC;
	}

	virtual float DTB() {
		return(LTC);
	}
};

class SVCLC :public SinhVien {
private:
	float DTCB;
public:
	void Nhap() {
		SinhVien::Nhap();
		cout << "\nNhap diem dien tu co ban: ";
		cin >> DTCB;
	}

	void Xuat() {
		SinhVien::Xuat();
		cout << "\nDiem dien tu co ban: " << DTCB;
		cout << "\nDiem trung binh: " << DTB();
	}

	friend istream& operator >>(istream& is, SinhVien& sv) {
		sv.Nhap();
		return is;
	}

	friend ostream& operator << (ostream& os, SinhVien& sv) {
		sv.Xuat();
		return os;
	}
	float DTB() {
		return ((2 * LTC) + DTCB) / 3;
	}
};

class SVChinhQuy : public SinhVien {

private:
	float NMKT;
public:
	/*
	SVChinhQuy() :SinhVien() {
		NMKT = 0;
	}*/

	void Nhap() {
		SinhVien::Nhap();
		cout << "\nNhap diem nhap mon ky thuat: ";
		cin >> NMKT;
	}

	void Xuat() {
		SinhVien::Xuat();
		cout << "\nDiem nhap mon ky thuat: " << NMKT;
		cout << "\nDiem trung binh: " << DTB();
	}

	float DTB() {
		return ((3 * LTC) + (2 * NMKT)) / 5;
	}
};

class Menu {
private:
	vector <SinhVien*> SV;
public:

	void Nhap() {
		int n;
		cout << "\nNhap tong so sinh vien: ";
		cin >> n;
		// chon doi tuong he
		SV.resize(n);
		for (int i = 0; i < n; i++) {
			cout << "\nSinh vien Chat luong cao (1), Sinh vien Chinh quy (2): ";
			int k;
			cin >> k;
			SinhVien* sv;
			if (k == 1)
				sv = new SVCLC;
			else
				sv = new SVChinhQuy;
			sv->Nhap();
			SV.push_back(sv);
		}
	}

	void Xuat() {
		cout << "\nDanh sach sinh vien: ";
		for (int i = 0; i < SV.size(); i++)
			SV.at(i)->Xuat();
	}

	void DTB() {
		for (int i = 0; i < SV.size(); i++)
			SV.at(i)->DTB();
	}

void SapXep() {
		SinhVien* temp;
		temp = new SinhVien;
		for (int i = 0; i < SV.size() - 1; i++) {
			for (int j = i + 1; j < SV.size(); i++) {
				if ((SV[i]->DTB()) < (SV[j]->DTB())) {
					temp = SV[i];
					SV[i] = SV[j];
					SV[j] = temp;
				}
			}
		}
		for (int i = 0; i < SV.size(); i++) {
			cout << "\nSap xep tang dan theo diem trung binh: ";
			SV[i]->Xuat();
		}
		delete temp;
	}

Ưu ái cho i quá, chỉ tăng i mà quên j.

3 Likes

Em sửa lại tăng j rồi mà vẫn còn lỗi. Báo là exception unhandled. 2 giá trị SV[i] và SV[j] vẫn còn NULL

ko cần SV.resize(n); vì em gọi SV.push_back(sv); rồi. Gọi resize thì SV sẽ tăng lên n phần tử, vòng for dưới em lại push_back n phần tử nữa thì SV sẽ có 2n phần tử, trong đó n phần tử đầu tiên là null pointer.

trong hàm SapXep ko cần gán temp = new SinhVien; và cũng ko cần delete temp;

ngoài ra:

  • SinhVien thiếu virtual destructor
  • Menu thiếu destructor để giải phóng các phần tử mà SV[i] trỏ tới
3 Likes

Bạn nghĩ sao về dòng cuối này. Nên nhớ rằng, trong quá trình sắp xếp, bạn đã gán temp = SV[i].

2 Likes

Em nghĩ khi cấp phát cho biến temp thì phải delete temp. Vậy em sai hả anh. Có phải sửa lại delete SV[i] đúng không ạ?

Vậy chỉ cần khai báo int temp đúng ko ạ?

Sao lại int được.

Bạn dùng đa hình tức là mảng bạn toàn con trỏ, nên bạn chỉ swap con trỏ với nhau thôi.

3 Likes

Dạ em làm được rồi ạ! Cám ơn mọi người!

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?