Обнаружено повреждение кучи: после нормального блока c ++ динамический c 2D массив - PullRequest
0 голосов
/ 25 января 2020

Я получаю эту ошибку Обнаружено повреждение кучи: после обычного блока ... Оно появляется только в том случае, если я пытаюсь освободить память моего 2D-массива examScores с помощью delete []. Я использовал для l oop для удаления каждого массива, так что я запутался, есть ли где-то утечка памяти? Я не очень знаком с управлением памятью, поэтому заранее благодарю за любую помощь

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;



string getGradeOfExam(double grade, double examAverage) {
    if (grade <= (examAverage - 15)) return "E";
    if (grade >= (examAverage + 15)) {
        return "A";
    }
    if (grade < (examAverage - 5)) return "D";
    if (grade > (examAverage + 5)) return "B";
    return "C";
}

string readNextName(ifstream& inputStream) {
    string firstName;
    string lastName;
    inputStream >> firstName;
    inputStream >> lastName;
    string fullName = firstName + " " + lastName;
    return fullName;
}
int readNextExamScore(ifstream& inputStream) {
    int examGrade;
    inputStream >> examGrade;
    return examGrade;
}

int main(int argc, char* argv[]) {
    if (argc < 3)
    {
        cerr << "Please provide name of input and output files";
        return 1;
    }
    cout << "Input file: " << argv[1] << endl;
    ifstream in(argv[1]);
    if (!in)
    {
        cerr << "Unable to open " << argv[1] << " for input";
        return 2;
    }
    cout << "Output file: " << argv[2] << endl;
    ofstream out(argv[2]);
    if (!out)
    {
        in.close();
        cerr << "Unable to open " << argv[2] << " for output";
        return 3;
    }

    int numStudents = 0;
    int numExams= 0;
    in >> numStudents >> numExams;

    string* studentNames = new string[numStudents];

    //first value corresponds to a specific student, second value corresponds to a specific exam
    int** examScores = new int* [numStudents];
    for (int i = 0; i < numExams; ++i) {
        examScores[i] = new int[numExams];
    }

    for (int i = 0; i < numStudents; i++) {
        studentNames[i] = readNextName(in);
        for (int j = 0; j < numExams; j++) {
            examScores[i][j] = readNextExamScore(in);
        }

    }
    //Finds averages of all exams and stores them in an array
    double* examAverages = new double[numExams];
    for (int i = 0; i < numExams; i++) {
        double examAverage = 0.0;
        double totalExamScore = 0.0;
        for (int j = 0; j < numStudents; j++) {
            totalExamScore += examScores[j][i];
        }
        examAverage = totalExamScore / numStudents;
        examAverages[i] = examAverage;
    }

    double totalExamScore = 0.0;
    double totalExamAverage = 0.0;
    for (int i = 0; i < numExams; i++) {
        totalExamScore += examAverages[i];
    }
    totalExamAverage = totalExamScore / numExams;

    double* studentAverages = new double[numStudents];

    for (int i = 0; i < numStudents; i++) {
        double studentTotalScore = 0.0;
        for (int j = 0; j < numExams; j++) {
            studentTotalScore += examScores[i][j];
        }
        studentAverages[i] = studentTotalScore / numExams;
    }

    //OUTPUT

    out << "Student Scores:" << endl;
    for (int i = 0; i < numStudents; i++) {
        out << right << setw(6) << studentNames[i] << "\t";
        for (int j = 0; j < numExams; j++) {
            out << examScores[i][j] << "\t";
        }
        out << endl;
    }
    out << endl;

    out << "Exam Averages:" << endl;
    for (int i = 0; i < numExams; i++) {
        out << setw(6) << "Exam " << i + 1 << " average = " << fixed << setprecision(1) << examAverages[i] << endl;
    }
    out << endl;

    out << "Student Exam Grades:" << endl;
    for (int i = 0; i < numStudents; i++) {
        out << right << setw(6) << studentNames[i] << "\t";
        for (int j = 0; j < numExams; j++) {
            out << examScores[i][j] << " ";
            out << "(" << getGradeOfExam(examScores[i][j], examAverages[j]) << ")\t";
        }
        out << endl;
    }
    out << endl;

    out << "Exam Grades:" << endl;
    for (int i = 0; i < numExams; i++) {
        int gradeCount[5] = { 0,0,0,0,0 };
        for (int j = 0; j < numStudents; j++) {
            if (getGradeOfExam(examScores[j][i], examAverages[i]) == "A") {
                gradeCount[0]++;
            }
            else if (getGradeOfExam(examScores[j][i], examAverages[i]) == "B") {
                gradeCount[1]++;
            }
            else if (getGradeOfExam(examScores[j][i], examAverages[i]) == "C") {
                gradeCount[2]++;
            }
            else if (getGradeOfExam(examScores[j][i], examAverages[i]) == "D") {
                gradeCount[3]++;
            }
            else if (getGradeOfExam(examScores[j][i], examAverages[i]) == "E") {
                gradeCount[4]++;
            }
        }
        out << setw(6) << "Exam " << i + 1 << "\t" << fixed << setprecision(1) << examAverages[i] << "\t";
        out << gradeCount[0] << "(A)" << "\t";
        out << gradeCount[1] << "(B)" << "\t";
        out << gradeCount[2] << "(C)" << "\t";
        out << gradeCount[3] << "(D)" << "\t";
        out << gradeCount[4] << "(E)" << endl;
    }
    out << endl;

    out << "Student final grades:" << endl;
    for (int i = 0; i < numStudents; i++) {
        out << studentNames[i] << "\t" << studentAverages[i] << "(" << getGradeOfExam(studentAverages[i], totalExamAverage) << ")" << endl;
    }
    out << "Class Average Score: " << totalExamAverage << endl;

    delete[] studentNames;

    for (int i = 0; i < numStudents; i++)
    {
        delete[] examScores[i];
    }
    delete[] examScores;

    delete[] examAverages;
    delete[] studentAverages;

    return 0;
}

Мой входной файл содержит следующее:

6 8
Cody Coder  84 100 100 70 100 80 100 65
Harry Houdini  77 68 65 100 96 100 86 100
Harry Potter  100 100 95 91 100 70 71 72
Mad Mulligun  88 96 100 90 93 100 100 100
George Washington  100 72 100 76 82 71 82 98
Abraham Lincoln  93 88 100 100 99 77 76 93

1 Ответ

2 голосов
/ 25 января 2020

Эта часть кажется подозрительной:

    int** examScores = new int* [numStudents];
    for (int i = 0; i < numExams; ++i) {
        examScores[i] = new int[numExams];
    }

Массив examScores имеет numStudents элементов, но верхняя граница для-l oop равна numExams.

Ошибки такого рода часто можно локализовать с помощью инструмента Valgrind. (Это сработало в этом случае.) Проверьте это.

...