Creating a function that allocates memory for an array of structures

I have a struct called Student which has a pointer to an array of testScores. I need to create a function that returns a pointer to the array of Student Structures. The function needs to allocate the memory needed for the array of students and the array of testScores for each student. The function takes two parameters, the number of students and the number of tests taken. I've gotten the allocation part down for the array of Students, but I'm not sure how I allocate memory for the testScores in the function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

struct Student {
    string name;
    int idNumber;
    int *testScores;
    double average;
    char grade;
    
};

Student *numberofStudentandTests(int, int);

int main(){
//Nothing here so far
}

Student *numberOfStudentandTests(int numStudents, int numTests){
    Student *ptr = nullptr;
    if (numStudents < 0){
        return nullptr;
    }
    ptr = new Student[numStudents];
    //allocate memory for the testScores array which is the size of the number of tests taken.

    return ptr;
}

You don't need to keep deleting and pasting your topic again.
huh? this is the first time i'm posting here and I haven't deleted anything.
Hi,
Firstly :
1
2
3
if (numStudents < 0){
        return nullptr;
    }

So if you have a numStudents of zero? The if-check, passes, but you will still get a student array of zero, and attempting to access it causes segfaults. This is how it should be :

1
2
3
if (numStudents <= 0){
        return nullptr;
    }
> // Allocate memory for the testScores array which is the size of the number of tests taken.

Use a for-loop :
1
2
for (int i = 0; i < numStudents; i++)
ptr[i].testScores = new int[numTests];
Does that help? :)
Thanks for the help, one more question, here's the full program. When I call the function to display studentInformation, it only shows the last student I entered. Like so:

How many students are in the class? 3
How many tests were taken by the students? 2
Enter the students first name: John
Enter the students last name: Smith
Enter the id number of the student: 123
Enter the score of test 1: 75
Enter the score of test 2: 82

Enter the students first name: Derek
Enter the students last name: Johns
Enter the id number of the student: 124
Enter the score of test 1: 79
Enter the score of test 2: 96

Enter the students first name: Max
Enter the students last name: Smith
Enter the id number of the student: 125
Enter the score of test 1: 95
Enter the score of test 2: 87

Student Name ID Number Test Average Grade
============ ========= ============ =====
Max Smith 125 91.0 A
0 0.0
0 0.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <iostream>
#include <iomanip>
#include <string>
#include <cstring>
#include <cstdlib>

using namespace std;

struct Student {
    string name;
    int idNumber;
    int *testGrades;
    double average;
    char grade;
};

Student *numberofStudentandTests(int, int);
void studentInfo(Student&, int);
void studentGrade(Student&);
void displayStudent(Student[], int);


int main(){
    int numberofStudents;
    int numberofTests;
    Student *studentInformation = nullptr;
    //Get the number of students in the class and validate the input
    cout << "How many students are in the class? ";
    cin >> numberofStudents;
    if (numberofStudents <= 0){
        cout << "Invalid amount entered, amount of students must be greater than 1. Please enter the number of students again. ";
        cin >> numberofStudents;
    }
    //Get the number of tests taken by the students and validate the input
    cout << "How many tests were taken by the students? ";
    cin >> numberofTests;
    if (numberofTests <= 0){
        cout << "Invalid amount entered, number of tests taken must be greater than 1. Please enter the number of tests taken again. ";
        cin >> numberofTests;
    }
    //Call function to allocate memory for Student structure array
    studentInformation = numberofStudentandTests(numberofStudents, numberofTests);
    for(int x = 0; x < numberofStudents; x++){
        studentInfo(*studentInformation, numberofTests);
        studentGrade(*studentInformation);
    }
    
    displayStudent(studentInformation, numberofStudents);
    
    delete [] studentInformation;
    delete [] studentInformation->testGrades;
}
//This function allocates memory for an array of Students and an array of test scores from each Student, it returns a pointer to the array of Student structure
Student *numberofStudentandTests(int numStudents, int numTests)
{
    Student *ptr = nullptr;
    if (numStudents <= 0){
        return nullptr;
    }
    ptr = new Student[numStudents];
    //allocate memory for the test scores
    for (int i = 0; i < numStudents; i++){
        ptr[i].testGrades = new int[numTests];
    }
    return ptr;
}
void studentInfo(Student &studentName, int numTests)
{
    string firstName;
    string lastName;
    cout << "Enter the students first name: ";
    cin >> firstName;
    cin.ignore();
    cout << "Enter the students last name: ";
    cin >> lastName;
    firstName += " " + lastName;
    studentName.name = firstName;
    cin.ignore();
    cout << "Enter the id number of the student: ";
    cin >> studentName.idNumber;
    cin.ignore();
    if (studentName.idNumber > 1000 || studentName.idNumber < 0){
        cout << "Invalid id number, id number must be between 0 and 1000, please enter the id number again: ";
        cin >> studentName.idNumber;
        cin.ignore();
    }
    int total = 0;
    //Get the test scores for each test and keep a running total
    for(int i = 0; i < numTests; i++){
        cout << "Enter the score of test " << (i+1) << ": ";
        cin >> studentName.testGrades[i];
        if(studentName.testGrades[i] > 100 || studentName.testGrades[i] <0){
            cout <<"Invalid test grade, grade must be between 0 and 100 points, please enter the score of the test " << (i+1) << " again: ";
            cin >> studentName.testGrades[i];
        }
        total += studentName.testGrades[i];
    }
    cout << endl;
    //Calculate the average
    studentName.average = total / numTests;
    
}
void studentGrade(Student &studentName)
{
    if (studentName.average >= 90)
        studentName.grade =  'A';
    else if (studentName.average >= 80)
        studentName.grade = 'B';
    else if (studentName.average >= 70)
        studentName.grade = 'C';
    else if (studentName.average >= 60)
        studentName.grade = 'D';
    else
        studentName.grade = 'F';
}
void displayStudent(Student studentName[], int numStudents)
{
    cout << setw(12) << "Student Name" << setw(18) << "ID Number" << setw(15) << "Test Average" << setw(10) << "Grade" << endl;
    cout << setw(12) << "============" << setw(18)<< "=========" << setw(15) << "============" << setw(10) << "=====" << endl;
    for(int i = 0; i < numStudents; i++)
    {
        cout << fixed << setprecision(1) << showpoint;
        cout << left << setw(12) << studentName[i].name << right << setw(18) << studentName[i].idNumber << setw(15) << studentName[i].average << setw(10) << studentName[i].grade << endl;
    }
    cout << endl;
}


I assume the problem lies with my call to the displayStudent function as the parameter takes in a Student array, but I'm not sure if it's the studentInfo function and I'm just storing the data improperly. When it displays the student info I'm only getting the last one which is printed first and then the fields are blank for the remaining two students in my example.
Last edited on
Hi,
1
2
3
4
for(int x = 0; x < numberofStudents; x++){
studentInfo(*studentInformation, numberofTests);
        studentGrade(*studentInformation);
}


You don't access every student info with index x. *studentInformation means it only accesses the first element, or studentInformation[0].

So :
1
2
studentInfo(studentInformation[x], numberofTests);
        studentGrade(studentInformation[x]);
Does that help? :)
Never mind I figured it out. I was thinking about it while I ate dinner and realized the same thing. Thanks for the help though.
Last edited on
Oh, good for you :)
Topic archived. No new replies allowed.