【问题标题】:Program crashes when input to double pointer array which is in struct point当输入到结构点中的双指针数组时程序崩溃
【发布时间】:2014-03-15 07:13:28
【问题描述】:

我被指示编写的程序是收集学生信息。这是非常基本的,但在说明中,我没有学生人数(不是问题)或每个学生的测试次数(问题)。我被指示创建一个指向结构的指针并为每个学生创建一个双指针数组。我这样做了。

但是,每次我尝试为学生输入考试成绩时,我的程序都会崩溃。我在 enterData() 函数中尝试了 studentData->testscores,我尝试了 studentData[i].testScores[j]、*studentData->testScores,但似乎没有任何效果。

谁能指出我正确的方向。

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

struct StudentInfo
{
    string name;
    string idNum;
    double* testScores;
    double average;
    char grade;
};

StudentInfo enterData(StudentInfo*, int, int);//Add data to the student
//void displayData(StudentInfo*, int);//Display the student info and grade

int main()
{
int numStudents;
int numTests;

cout << "Enter the amount of students to input: ";
cin >> numStudents;
cin.ignore();
cout << "Enter the number of test scores per students: ";
cin >> numTests;
cin.ignore();

StudentInfo* studentData = new StudentInfo[numStudents];

for(int i = 0; i < numStudents; i++);
{
    studentData->testScores = new double[numTests];
    studentData++;
}


//Let the user enter students information
enterData(studentData, numStudents, numTests);

return 0;
}
//*************************
//define enterData function
//*************************
StudentInfo enterData(StudentInfo* studentData, int numStudents, int numTests)
{
int testTotal = 0; //Keep a total of the tests.
double testScore; //Variable to hold user input of test score.
for(int i = 0; i < numStudents; i++)
    {
    cout << "\n\nPlease enter data for Student #" << i + 1;
    cout << "\n-------------------------------------\n";
    cout << "\nName: ";
    getline(cin, studentData[i].name);
    while(studentData[i].name.empty())
    {
        cout << "Oops! You didn't enter the students's name!" << endl;
        cout << "Please enter customer's name: ";
        getline (cin, studentData[i].name);
    }
    //Get Student's Id Number
    cout << "ID Number: ";
    getline(cin, studentData[i].idNum);
    while(studentData[i].idNum.empty())
    {
        cout << "Oops! You didn't enter the students's ID Number!" << endl;
        cout << "Please enter student's ID Number: ";
        getline (cin, studentData[i].idNum);
    }
        //Get Student's Test Scores
        cout << "Enter Test Scores for Student #" << i + 1 << endl;

        for (int j = 0; j < numTests; j++)
        {
            cout << "Test #" << j + 1 << ": ";
            cin >> testScore;
            cin.ignore();
            studentData[i].testScores[j] = testScore;
            testTotal += testScore;
        }
    //Save Students Average
    cout << fixed << setprecision(2);
    cout << "Student's Average: " << testTotal/numTests;

    studentData[i].average = testTotal/numTests;

    //Save Students Grade
    if(studentData[i].average > 90)
        studentData[i].grade = 'A';
    else if(studentData[i].average > 80)
        studentData[i].grade = 'B';
    else if(studentData[i].average > 70)
        studentData[i].grade = 'C';
    else if(studentData[i].average > 60)
        studentData[i].grade = 'D';
    else
            studentData[i].grade = 'F';
        cout << "Student's Grade: " << studentData[i].grade << endl;

    }
    return *studentData;
}

【问题讨论】:

  • 清理代码:删除与您的问题无关的部分,并测试它是否重现了问题。

标签: c++ arrays pointers struct


【解决方案1】:

您遇到未定义的行为,因为您试图访问数组边界之外的内存:

// you create an array and keep pointer to first element:
StudentInfo* studentData = new StudentInfo[numStudents];

// try to increment this pointer till it points behind this array:
for(int i = 0; i < numStudents; i++);                        // <-- semicolon !!!
{
    studentData->testScores = new double[numTests];
    studentData++;
}

// and use this pointer that points to incorrect memory:
enterData(studentData, numStudents, numTests);

此外,for 之后有一个分号,它会导致循环的“主体”(因为分号只不过是匿名嵌套范围)执行一次,这足以让函数 enterData 执行从第二个元素开始迭代学生,最后调用 UB。


你应该做的是:

StudentInfo* studentData = new StudentInfo[numStudents];

for(int i = 0; i < numStudents; i++) {
    studentData[i].testScores = new double[numTests];
}

enterData(studentData, numStudents, numTests);

...提醒您,请注意清理它应该反映它的分配方式:

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

【讨论】:

  • 更不用说for后面的分号了,所以循环甚至不会被执行......
  • 我真的很感激。我试图将指针符号与“studentData->testScores”一起使用。在 for 循环之后处理分号确实没有任何帮助。 :) 死亡分号。谢谢,现在可以使用了!
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 2022-01-10
  • 2021-12-27
  • 1970-01-01
相关资源
最近更新 更多