Reputation: 571
I am trying to run the following code but it crashes as soon as the object of inherited class is created.
The program works fine until the creation of the inherited class object but segmentation fault occurs after "Student *s" line is executed.
Here's the code:
#include <iostream>
#include <vector>
using namespace std;
class Person
{
protected:
string firstName;
string lastName;
int id;
public:
Person(string firstName, string lastName, int identification)
{
this->firstName = firstName;
this->lastName = lastName;
this->id = identification;
}
void printPerson()
{
cout << "Name: " << lastName << ", " << firstName << "\nID: " << id
<< "\n";
}
};
class Student: public Person
{
private:
vector<int> testScores;
public:
Student(string f, string l, int i, vector<int>& scores) :
Person(firstName, lastName, id)
{
this->firstName = f;
this->lastName = l;
this->id = i;
this->testScores = scores;
}
char calculate()
{
vector<int>::iterator it;
int sum = 0;
for (it = testScores.begin(); it != testScores.end(); it++)
{
sum += *it;
}
int avg = sum / (testScores.size());
if (avg >= 90 && avg <= 100)
return 'O';
else if (avg >= 80 && avg < 90)
return 'E';
else if (avg >= 70 && avg < 80)
return 'A';
else if (avg >= 55 && avg < 70)
return 'P';
else if (avg >= 40 && avg < 55)
return 'D';
else
return 'T';
}
};
int main()
{
string firstName;
string lastName;
int id;
int numScores;
cin >> firstName >> lastName >> id >> numScores;
vector<int> scores;
for (int i = 0; i < numScores; i++)
{
int tmpScore;
cin >> tmpScore;
scores.push_back(tmpScore);
}
cout << "Calling\n";
Student* s = new Student(firstName, lastName, id, scores);
cout << "Done\n";
s->printPerson();
cout << "Grade: " << s->calculate() << "\n";
return 0;
}
Upvotes: 0
Views: 363
Reputation: 33931
Student(string f, string l, int i, vector<int>& scores) :
Person(firstName, lastName, id)
uses Person
's own firstName
, lastName
, and id
members to construct Person
. This may or may not segfault and go boom, but is definitely going into undefined behaviour.
OP wants something more like this where the passed parameters are used instead:
Student(string f, string l, int i, vector<int>& scores) :
Person(f, l, i)
{
// all of the members that were set here don't need to be set.
// Person did it already
this->testScores = scores;
}
One more improvement can be made. testScores
can be initialized with the member initializer list. This allows scores
to be stuffed into testScores
immediately and the compiler can make all sorts of interesting optimizations.
Student(string f, string l, int i, vector<int>& scores) :
Person(f, l, i), testScores(scores)
{
}
Where possible initialize member variables in the initializer list. `Person can be improved as well:
Person(string first, string last, int identification):
firstName(first),
lastName(last),
id(identification)
{
}
Now the divide by zero bug spotted by Rakete1111's can be found and fixed.
Upvotes: 1