Segmentation Fault on Simple C++ Program - c++

This is a follow up to my previous question. I have some code which should be running fine, and it does for the most part. When I run it, most of the main method runs but I get a segmentation fault when the getter methods are executed. Here is the code:
#include <iostream>
#include <string>
using namespace std;
class Person
{
protected:
string m_FirstName, m_LastName, m_email;
public:
Person(){}
Person(const string& firstName, const string& lastName) :
m_FirstName(firstName), m_LastName(lastName)
{}
string get_name() const
{
return m_FirstName;
}
string get_surname() const
{
return m_LastName;
}
bool has_email_p()
{
}
};
class Person_with_telephone: public Person
{
protected:
string m_telephone;
public:
Person_with_telephone(){}
Person_with_telephone(const string& telephone) : m_telephone(telephone)
{}
bool has_telephone_p()
{
if (m_telephone == "")
{
cout << "You have no phone number registered" << endl;
return false;
}
else
{
cout << "Your number is: " << m_telephone << endl;
return true;
}
}
string get_telephone() const
{
return m_telephone;
}
string set_telephone()
{
}
string get_telephone()
{
}
};
int main()
{
string f, l, ph;
cout << "Enter fist name: ";
cin >> f;
cout << "Enter Last name: ";
cin >> l;
cout << "Enter telephone number: ";
cin >> ph;
Person p(f, l);
Person_with_telephone pwt(ph);
cout << "Your name is: " << p.get_name() << " " << p.get_surname() << endl;
cout << "Has telephone? " << endl << " Your number is: " << pwt.get_telephone() << endl;
return 0;
}
When I compile it compiles fine and when I run I get asked for the three inputs of Name, Surname and Telephone, but when I input the last value I get this:Odd segfault

You are not returning anything in Person_with_telephone::get_telephone(). This will cause a segfault.
If you compile with proper warnings turned on Then you should at least get
main.cpp:32:9: warning: control reaches end of non-void function [-Wreturn-type]
}
^
main.cpp:69:3: warning: control reaches end of non-void function [-Wreturn-type]
}
^
main.cpp:74:3: warning: control reaches end of non-void function [-Wreturn-type]
}
^
3 warnings generated.
Which would let you know that you need return statements in those functions.

Your bool has_email_p(), string get_telephone() and string set_telephone() functions don't do or, more importantly, return anything.

Related

error C2065: 'firstName': undeclared identifier

So I have my header and my CPP for that class. My understanding is that although StudentID is a private variable in StudentClass.h I assign it to
StudentID = FullStudentID; under my set statement so it should work. Hoewever, I get error C2065: 'firstName': undeclared identifier. Tried all solutions I found but none work.
Am I setting up these variables incorrectly? I tried to have the variables as protected rather than private but same issue.
Header
#define Student_H
#include <iostream>
#include <string>
using namespace std;
class Student {
public:
void SetStudentID(int FullStudentID);
void SetAge(int ageInYears);
void SetFirstName(string firstAName);
void SetLastName(string lastAName);
void SetEmail(string aEmailAddress);
int GetStudentID() const;
int GetAge() const;
string GetFirstName() const;
string GetLastName() const;
string GetEmail() const;
private:
int studentID;
int age;
string firstName;
string lastName;
string emailAddress;
};
#endif
Source
#include "StudentClass.h"
#include <iostream>
#include <string>
using namespace std;
void Student::SetStudentID(int FullStudentID) {
studentID = FullStudentID;
return;
}
void Student::SetAge(int ageInYears) {
age = ageInYears;
return;
}
void Student::SetFirstName(string firstAName) {
firstName = firstAName;
return;
}
void Student::SetLastName(string lastAName) {
lastName = lastAName;
return;
}
void Student::SetEmail(string aEmailAddress) {
emailAddress = aEmailAddress;
return;
}
//start of get statements -------------------------------------------------------------------
int Student::GetStudentID() const {
return;
}
int Student::GetAge() const {
return;
}
string Student::GetFirstName()const {
return;
}
string Student::GetLastName()const {
return;
}
string Student::GetEmail()const {
return;
}
void StudentPrint() const {
cout << "student ID: " << studentID << endl;
cout << "age: " << age << endl;
cout << "First name: " << firstName << endl;
cout << "Last name: " << lastName << endl;
cout << "Email: " << emailAddress << endl;
}
StudentPrint is not a member function of Student and can thus not access those variables. Either make it a member function of Student, or better yet, use the 'get' functions you've defined (after you've actually implemented them).
void StudentPrint(const Student& student) {
cout << "student ID: " << student.GetStudentID() << endl;
cout << "age: " << student.GetAge() << endl;
cout << "First name: " << student.GetFirstName() << endl;
cout << "Last name: " << student.GetLastName() << endl;
cout << "Email: " << student.GetEmailAddress() << endl;
}
As a side note; StudentPrint cannot be marked as const as it's not a member function, but a free function. Only member functions can be marked as const.
Not sure how to mark a selection as the fix but
"How is StudentPrint supposed to print a student's information? Either make it a member function, or pass in a Student object as a parameter. – cigien 8 mins ago"
Called it. I forgot to include the print as a member function. Now I'm getting declaration errors but I'll try to sort that out my self and post a new question if it comes up. Thanks everyone you're awesome!

vector of pointers to class objects

I'm having a problem understanding vectors of pointers to class objects, I tried a test code to try and understand it but whenever I enter a name and try to output it, it prints out numbers instead of the actual name that I entered. I'm hoping someone can explain this to me as I'm new to these concepts.
Also
Pets[0]->print(); dosent print at all while:
cout << "in main: " << Pets[0] << endl;
prints.
class Pet
{
public:
string name;
Pet(const string&);
string getName() const
{
return name;
}
void setName(const string& Name)
{
name = Name;
}
void print()const;
}
int main()
{
vector<Pet*> Pets;
string names;
int done = NULL;
do
{
{
cout << "Name: ";
cin >> names;
Pets.push_back(new Pet(names));
cin.ignore();
}
cout << "Add another ?" << endl;
cin >> done;
} while (done != 0);
Pets[0]->print();
cout << "in main: " << Pets[0] << endl;
system("pause");
}
Pet::Pet(const string& Name)
{
}
void Pet::print()const
{
cout << "Name: " << name;
}
The constructor of Pet does not assign the parameter, hence it remains empty.
Write...
Pet::Pet(const string& Name) : name(Name) { }
to do this initialization.

Error showing "terminate called after throwing an instance of 'std::bad_alloc'"

When i run this program it get fatal error and program got stopped. I think this problem is due to string type of may be using std::string. because when i use char data type it was runs correctly. What is the problem kindly guide.
parcel.cpp
#include "Parcel.h"
#include <iostream>
#include <string>
using namespace std;
bool check = false;
// Constructor
Parcel::Parcel(int id, std::string senderName, std::string senderAddress, std::string receiverName, std::string receiverAddress, int weight, int fee){
this->id = id;
this->senderName = senderName;
this->senderAddress = senderAddress;
this->receiverName = receiverName;
this->receiverAddress = receiverAddress;
this->weight = weight;
this->fee = fee;
};
// Destructor
Parcel::~Parcel() {
cout << "Destructor called";
}
// Defination of setter
void Parcel::setID(int id) {
this->id = id;
if(id < 0) {
cout << endl << "Error: Please write valid receipt number e.g. 0 to onward";
}
}
void Parcel::setWeight(int weight) {
this->weight = weight;
if(weight < 0) {
cout << endl << "Error: Please write valid weight e.g. above to 0 grams";
}
}
void Parcel::setFee(int fee) {
this->fee = fee;
if(fee < 0) {
cout << endl << "Error: Please write valid fee e.g. 0 to onward";
}
}
void Parcel::setSenderName(std::string senderName) {
this->senderName = senderName;
// if(strlen(senderName) == 0) {
// cout << endl << "Error: Please write sender name";
// }
}
void Parcel::setSenderAddress(std::string senderAddress) {
this->senderAddress = senderAddress;
// if(senderAddress == 0) {
// cout << endl << "Error: Please write sender address";
// }
}
void Parcel::setReceiverName(std::string receiverName) {
this->receiverName = receiverName;
// if(receiverName == 0) {
// cout << endl << "Error: Please write reciever name";
// }
}
void Parcel::setReceiverAddress(std::string receiverAddress) {
this->receiverAddress = receiverAddress;
// if(receiverAddress == 0) {
// cout << endl << "Error: Please write reciever address";
// }
}
// Defination of getter
int Parcel::getID() {
return id;
}
int Parcel::getWeight() {
return weight;
}
int Parcel::getFee() {
return fee;
}
string Parcel::getSenderName() {
return senderName;
}
string Parcel::getSenderAddress() {
return senderAddress;
}
string Parcel::getReceiverName() {
return receiverName;
}
string Parcel::getReceiverAddress() {
return receiverAddress;
}
parcel.h
#ifndef PARCEL_H
#define PARCEL_H
#include <iostream>
#include <string>
class Parcel
{
private:
// Declare data members
int id, weight, fee;
std::string senderName, senderAddress, receiverName, receiverAddress;
public:
// Setter function
void setID(int id);
void setWeight(int weight);
void setFee(int fee);
void setSenderName(std::string senderName);
void setSenderAddress(std::string senderAddress);
void setReceiverName(std::string receiverName);
void setReceiverAddress(std::string receiverAddress);
// getter function
int getID();
int getWeight();
int getFee();
std::string getSenderName();
std::string getSenderAddress();
std::string getReceiverName();
std::string getReceiverAddress();
// Constructor
Parcel(int id, std::string senderName, std::string senderAddress, std::string receiverName, std::string receiverAddress, int weight, int fee);
// Destructor
~Parcel();
protected:
};
#endif
main.cpp
#include <iostream>
#include "Parcel.h"
#include <string>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
// Data member to take input from user
int id, weight, fee;
std::string senderName, senderAddress, receiverName, receiverAddress;
// main function
int main(int argc, char** argv) {
cout << "Please enter receipt number: ";
cin >> id;
cout << "Please enter sender name: ";
cin >> senderName;
cout << "Please enter sender address: ";
cin >> senderAddress;
cout << "Please enter receiver name: ";
cin >> receiverName;
cout << "Please enter receiver address: ";
cin >> receiverAddress;
cout << "Please enter parcel weight(gms): ";
cin >> weight;
cout << "Please enter parcel fee: ";
cin >> fee;
// Instance of Parcel class
Parcel parcel(parcel.getID(), parcel.getSenderName(), parcel.getSenderAddress(), parcel.getReceiverName(), parcel.getReceiverAddress(), parcel.getWeight(), parcel.getFee());
// Set values
parcel.setID(id);
parcel.setSenderName(senderName);
parcel.setSenderAddress(senderAddress);
parcel.setReceiverName(receiverName);
parcel.setReceiverAddress(receiverAddress);
parcel.setWeight(weight);
parcel.setFee(fee);
// Make output to show on console
cout << endl << endl;
cout << "Shipment Receipt" << endl << "___________________________________________" << endl;
cout << "Receipt No.: " << parcel.getID() << endl << "Sender Name: " << parcel.getSenderName() << endl
<< "Sender Address: " << parcel.getSenderAddress() << endl << "Receiver Name: " << parcel.getReceiverName() << endl
<< "Receiver Address: " << parcel.getReceiverAddress() << endl << "Parcel Weight: " << parcel.getWeight() << endl
<< "Parcel Shipping Charges: " << parcel.getFee() << endl;
// Destructor call
parcel.~Parcel();
}
Parcel parcel(parcel.getID(), parcel.getSenderName(), parcel.getSenderAddress(), parcel.getReceiverName(), parcel.getReceiverAddress(), parcel.getWeight(), parcel.getFee());
Don't do that. You are calling parcel.getSenderName() before the parcel object is fully initialized.
Your program doesn't terminate with instance of bad alloc when I tried to run. However, it does get warnings because of this line
Parcel parcel(parcel.getID(), parcel.getSenderName(), parcel.getSenderAddress(), parcel.getReceiverName(), parcel.getReceiverAddress(), parcel.getWeight(), parcel.getFee());
You should consider a default constructor Parcel() with default values assigned to different attributes and then Parcel parcel before assigning them in main()
What arguments did you run your program with?
Your construction,
Parcel parcel(parcel.getID(), parcel.getSenderName(), parcel.getSenderAddress(), parcel.getReceiverName(), parcel.getReceiverAddress(), parcel.getWeight(), parcel.getFee());
initialises parcel with itself, which is uninitialised.
This is undefined, and anything can happen.
You've already read all parameters from the user, so use them:
Parcel parcel(id, senderName, senderAddress, receiverName, receiverAddress, weight, fee);
You can remove the entire sequence of setters.
And you should not call the destructor; C++ handles destruction automatically.
If you found that idea in a book, throw it away immediately and look for a better one here.
If you don't have a book, look in the same place.

C++ chain inheritance

Im trying to create a percent savings program for a supermarket with 3 inherited classes (PersonData -> CustomerData -> PreferredCustomer). The entire program has to follow this UML diagram:
I am having problems with the third class; specifically initializing values in the first constructor of the class. Im getting an error message in visual studio: "redefinition of formal parameter Pa" and "redefinition of formal parameter "dl".
This is the constructor with the errors:
PreferredCustomer(string aLname, string aFname, string aAddress,
string aCity, string aState, int aZip, string aPhone, int cn,
bool ml, double Pa, double dl) // constructor 1
{
double Pa;
double dl;
}
The parameters in this third child constructor have been overloaded from the parent constructor. Arguments cn, ml, Pa, dl have all been added into this parameter.
I'm not sure why i am getting these errors? Also, should i be creating a virtual function or using pointers? Thank you for any help.
My program source code (for reference):
#include <iostream>
#include <string>
using namespace std;
class PersonData // PersonData parent class defined
{
private:
string lastName;
string firstName;
string address;
string city;
string state;
string phone;
int zip;
public:
PersonData() // Default Constructor initialization
{
lastName = " ";
firstName = " ";
address = " ";
city = " ";
state = " ";
zip = 0;
phone = " ";
}
PersonData(string aLname, string aFname, string aAddress, string aCity, string aState, int aZip, string aPhone) // Constructor 1
{
lastName = aLname;
firstName = aFname;
address = aAddress;
city = aCity;
state = aState;
zip = aZip;
phone = aPhone;
}
// Accesor Functions
string getLastName() const
{
return lastName;
}
string getFirstName() const
{
return firstName;
}
string getAddress() const
{
return address;
}
string getCity() const
{
return city;
}
string getState() const
{
return state;
}
int getZip() const
{
return zip;
}
string getPhone() const
{
return phone;
}
// Mutator Functions
void setLastName(string aLname)
{
lastName = aLname;
}
void setFirstName(string aFname)
{
firstName = aFname;
}
void setAddress(string aAddress)
{
address = aAddress;
}
void setCity(string aCity)
{
city = aCity;
}
void setState(string aState)
{
state = aState;
}
void setZip(int aZip)
{
zip = aZip;
}
void setPhone(string aPhone)
{
phone = aPhone;
}
};
class CustomerData :public PersonData // CustomerData child class of PersonData base class
{
private:
int customerNumber;
bool mailingList;
public:
CustomerData() // Default constructor
{
customerNumber = 0;
mailingList = 0;
}
CustomerData(int cNum, bool mailL) // Constructor 1
{
setCustomerNumber(cNum);
setMailingList(mailL);
}
// Accessor Functions for child class
int getCustomerNumber() const
{
return customerNumber;
}
bool getMailingList() const
{
if (mailingList != 0)
{
cout << "On Mailing List!: ";
return mailingList;
}
else (mailingList == 0);
{
cout << "Not on mailing list!: ";
return mailingList;
}
}
// Mutator Functions for child class
void setCustomerNumber(int cNum)
{
customerNumber = cNum;
}
void setMailingList(bool mailL)
{
mailingList = mailL;
}
};
class PreferredCustomer :public CustomerData // child class of CustomerData child class
{
private:
double purchasesAmount;
double discountLevel;
public:
PreferredCustomer() // default constructor
{
purchasesAmount = 0;
discountLevel = 0;
}
PreferredCustomer(string aLname, string aFname, string aAddress,
string aCity, string aState, int aZip, string aPhone, int cn,
bool ml, double Pa, double dl) // constructor 1
{
double Pa;
double dl;
}
// Mutator Functions
void setPurchasesAmount(double Pa)
{
purchasesAmount = Pa;
}
// Accessor Functions
double getPurchasesAmount() const
{
return purchasesAmount;
}
double getDiscountLevel() const
{
return discountLevel;
}
void addPurchase(double P) const
{
}
};
int main()
{
CustomerData Cdata; // for access of child class functions
PersonData Pdata; // for access of parent class functions
PreferredCustomer PCdata; // for access of preferred customer class functions
string temp1; // Temporary variable for string values
int temp2, // Temporary variable for integer values
max = 100, // For-loop maximum loop value
i; // i variable
bool temp3; // Temporary variable for bool values
for (i = 1; i <= max; i++)
{
// Input Data
cout << "Please input first Name: ";
getline(cin, temp1);
Pdata.setFirstName(temp1);
cout << "Please input last Name: ";
getline(cin, temp1);
Pdata.setLastName(temp1);
cout << "Please input address: ";
getline(cin, temp1);
Pdata.setAddress(temp1);
cout << "Please input city: ";
getline(cin, temp1);
Pdata.setCity(temp1);
cout << "Please input state: ";
getline(cin, temp1);
Pdata.setState(temp1);
cout << "Please input Zip code: ";
cin >> temp2;
Pdata.setZip(temp2);
cin.ignore(); // discards unread char from cin
cout << "Please input Phone Number: ";
getline(cin, temp1);
Pdata.setPhone(temp1);
cout << "Enter 1 to be included in mail list," << endl;
cout << "Enter 0 to not be included in mail list: ";
cin >> temp3;
Cdata.setMailingList(temp3);
Cdata.setCustomerNumber(i); // set customer number
cout << endl << endl;
cout << "Name: " << Pdata.getFirstName() << ", " << Pdata.getLastName() << " \n";
cout << "Customer Number: " << Cdata.getCustomerNumber() << "\n";
cout << "Address: " << Pdata.getAddress() << "\n";
cout << "City: " << Pdata.getCity() << "\n";
cout << "State: " << Pdata.getState() << "\n";
cout << "Phone: " << Pdata.getPhone() << "\n";
cout << "Zip: " << Pdata.getZip() << "\n";
cout << Cdata.getMailingList() << "\n";
cout << endl << endl;
cin.ignore(); // discards unread char from cin
}
char c;
cin >> c;
return 0;
}
A constructor's purpose is to take the parameters the are passed in and construct the object from the class declaration and initialize members as appropriate. It not only has to initialize the class but also all the base classes as well, this can be done by passing parameters to the base constructor(s).
In
PreferredCustomer(string aLname, string aFname, string aAddress,
string aCity, string aState, int aZip, string aPhone, int cn,
bool ml, double Pa, double dl) // constructor 1
{
double Pa;
double dl;
}
You aren't initializing anything
You are declaring two local parameters that match (and conflict with) the parameters passed in
You don't call the base's constructors (how most of the work is done)
PreferredCustomer(...) :CustomerData(...)
CustomerData(...) :PersonData(...)
You don't initialize this class's members
purchasesAmount = pa;
discountLevel = dl;

C++ help setting up pointers in classes

I'm currently having some problems with my class and the member functions, particularly with taking the users input from the setter functions and then displaying that info from the print info function. I have a separate functions that allow the user to enter information about the character and then a getter function to then use in printing out the info that the user entered. When I first ran it I had an error about needing to use a pointer to a member function and I added the &Character::GetCharacterName and the others in my print info function. Now when I run the program through my main function (I didn't include it because it simply calls all the functions) my program will run but all the values are set at 1 no matter what the user entered. I know it has something to do with pointers so any help with correctly setting this up so that it returns the values that the user entered would be appreciated. Thanks
Character.h file
class Character
{
public:
Character();
void SetCharacterName();
void SetCharacterType();
void SetCharacterLevel();
string GetCharacterName();
string GetCharacterType();
double GetCharacterLevel();
void PrintInfo();
private:
string CharacterName;
string CharacterType;
double CharacterLevel;
};
Character.cpp file
Character::Character()
{
CharacterLevel = 1.0;
}
void Character::SetCharacterName()
{
cout << "\nWhat is the character's name? ";
cin >> CharacterName;
}
void Character::SetCharacterType()
{
cout << "\nWhat is the character's type? ";
cin >> CharacterType;
}
void Character::SetCharacterLevel()
{
cout << "\nWhat is the character's level? ";
cin >> CharacterLevel;
}
string Character::GetCharacterName()
{
return CharacterName;
}
string Character::GetCharacterType()
{
return CharacterType;
}
double Character::GetCharacterLevel()
{
return CharacterLevel;
}
void Character::PrintInfo()
{
system("pause");
system("cls");
cout << "\nCharacter name is " << &Character::GetCharacterName << ".\n";
cout << "\nCharacter type is " << &Character::GetCharacterType << ".\n";
cout << "\nCharacter level is " << &Character::GetCharacterLevel << ".\n";
}
Use (), to do a method call in PrintInfo:
cout << "\nCharacter name is " << GetCharacterName() << ".\n";
etc.
I sugest :
this->GetCharacterName();
In the print method.