Segmentation fault in header file - class

I have defined a Parent.h file, having Parent class with following data members:-
#pragma once
#include <string>
using namespace std;
class Person
{
private:
string id;
string name;
string email;
int contact_number;
string address;
public:
Person();
~Person();
void set_id(string);
void set_name(string);
void set_email(string);
void set_contact_number(int);
void set_address(string);
string get_id();
string get_name();
string get_email();
int get_contact_number();
string get_address();
};
Person::Person()
{
this->id = "";
this->name = "";
this->email = "";
this->contact_number = 0;
this->address = "";
}
void Person::set_id(string id)
{
this->id =id;
}
I have defined the rest of the functions(setters and getters) likewise in Parent.h file.
After that I am making a child class in Student.h header file, this Student class will publicly inherit the Parent class
#pragma once
#include"Courses.h" //course is aggregating to a student
#include"AcademicRecord.h"
#include "Person.h"
#include "Department.h"
#include<string>
#include<vector>
using namespace std;
class Student:public Person,public AcademicRecord,public Department
{
private:
string institute_email;
public:
Courses A;//A contains all information about the courses a student has opt for.
Student();
~Student();
//Using polymorphism between methods
void ShowStudentAcademicRecord(); //shows the academic record of current student
void ShowStudentCoursesInfo(); //getting the information for all courses of student
//setter
void set_institute_email(string email);
void setDepartmentID(string);
//getter
string get_institute_email();
};
After that I have a Display.h file having vector of Students as its Data member and using a member function in Display, I am asking user to input data members like ID,Name,Address,... for individual students.
#include "Student.h"
using namespace std;
class Display
{
public:
vector<Student> students;
Display();//default constructor
//setter
void setStudentData();
};
void Display::setStudentData()
{
int size;
cout<<"Enter the number of students: ";
cin>>size;
Student *current; //current Student
for (int i = 0; i < size; i++)
{
current = &students[i];
cout<<"For student "<<i+1<<"\nEnter the following: \n";//For general details
cout<<"ID Name Email Contact_Number Address Institute_Email\n";
string ID,Name,EMail,Address,insti_email;
int contact_number;
cin>>ID>>Name>>EMail>>contact_number>>Address>>insti_email;
current->set_id(ID);
current->set_name(Name);
current->set_email(EMail);
current->set_contact_number(contact_number);
current->set_address(Address);
current->set_institute_email(insti_email);
}
And when I try inserting value insides students by executing main.cpp file.
I get segmentation fault at run-time inside Person class at setter function, where the first setter I have declared inside the class is void set_id(string).
#include "Display.h"
#include<vector>
#include<string>
int main()
{
Display display;
display.setStudentData();
}
Error:-
I tried:-
1.Rechecking the setter function for any error
2.Bring all the classes inside the main.cpp file,instead of header files, but still the error continues.
I expected the program to take the desired input for various data members of student elments of vector students inside Display class.
Instead I got a seg-fault.
Please if anyone can tell me what I have done wrong, or do I have to do malloc somewhere, inside a function?

As Nate Eldredge, has said I should use push_back instead of accessing ith element of students vector in setStudentData() function, as initially during default declaration of a Display class, the students vector is empty. Hence trying to access students[i] in current = &students[i], I am getting segmentation fault.
The appropriate code for Display.h should be then
#include "Student.h"
using namespace std;
class Display
{
public:
vector<Student> students;
Display();//default constructor
//setter
void setStudentData();
};
void Display::setStudentData()
{
int size;
cout<<"Enter the number of students: ";
cin>>size;
total_students += size;
Student *temp =new Student(); //temp Student
for (int i = 0; i < size; i++)
{
cout<<"For student "<<i+1<<"\nEnter the following: \n";//For general details
cout<<"ID Name Email Contact_Number Address Faculty_Type Faculty_Description\n";
string ID,Name,EMail,Address,insti_email;
int contact_number;
cin>>ID>>Name>>EMail>>contact_number>>Address>>insti_email;
temp->set_id(ID);
temp->set_name(Name);
temp->set_email(EMail);
temp->set_contact_number(contact_number);
temp->set_address(Address);
temp->set_institute_email(insti_email);
cout<<"Enter the Course Details: \n";//For Course Details
int size_course;
cout<<"Enter the number of courses: ";
cin>>size_course;
cout<<"Enter the following for each course: \n";
cout<<"Course_Name Marks Attendance Percentage \n";
string name;
int marks;
float attendance;
for (int i = 0; i < size_course; i++)
{
cin>>name>>marks>>attendance;
temp->A.set_courses_enrolled(name);
temp->A.set_course_wise_marks(marks);
temp->A.set_coursewise_attendance_percentage(attendance);
}
cout<<"Enter the Academic Record Details: \n";//For Academic Record Details
string program_name; int admission_no, enroll_no, begin_year, end_year, credits; float CGPA;
cout<<"Enter Program_name, admission_no enroll_no begin_year end_year credits CGPA";
cin>>program_name>>admission_no>>enroll_no>>begin_year>>end_year>>credits>>CGPA;
setStudentAcademicRecord(temp,i,program_name,admission_no,enroll_no,begin_year,end_year,credits,CGPA); //passing temp pointer in this one
students.push_back(*temp); //adding a new student in students vector
}

Related

I am not able to access private variables of class, I have used friend class

#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Movie
{
private:
std::string name{};
std::string rating{};
int watched{};
friend class movies;
public:
Movie(std::string name_val, std::string rating_val, int watched_val = 0);
// copy constructor
Movie(const Movie &source); //// this constructor
};
Movie::Movie(std::string name_val, std::string rating_val, int watched_val)
:name{name_val}, rating{rating_val}, watched{watched_val}{}
Movie::Movie(const Movie &source){
name = source.name;
rating = source.rating;
watched = source.watched;
}
class Movies
{
private:
std::vector<Movie> movie_obj;
public:
void get_movie_byname(Movie &abc) { std::cout << abc.name; }; // here is error abc.name
};
here is the error message
main.cpp:53:53: error: 'std::string Movie::name' is private within this context
53 | void get_movie_byname(Movie &abc) { std::cout << abc.name; };
| ^~~~
main.cpp:11:21: note: declared private here
11 | std::string name {};
| ^~~~
cant understand whats wrong...
i think friend of a class is friend of for given obj ( this--> ), and not for all obj,
if i removed copy constructor of Movie, error resolved!
cant understand relation between copy constructor and friend.
// issue solved turns out its just typo in Movies, declaration in friend declaration.

C++\CLI Windows Forms - creating external class

While making a simple windows forms application with VC++ I have a listview containing some files and their info. What I want to do is only show the filename in the list while storing the full filepath. I created an external class to do this:
class FileInfoContainer {
vector<string> filenames;
vector<int> uncompsize;
vector<int> compsize;
int getFileSize(string filepath);
public:
FileInfoContainer() {};
void AddItem(string filepath);
void AddItem(string filepath, int uncompsize, int compsize);
void AddItem(string filepath, int uncompsize);
string getItemFilename(int index);
int getItemCompsize(int index);
int getItemUncompsize(int index);
};
Now back to the automatic code generated by the VS template for this application, I tried to declare an instance of this class so that I can have the file information available anywhere within:
public ref class MainForm : public System::Windows::Forms::Form
{
public:
MainForm(void)
{
InitializeComponent();
}
protected:
~MainForm()
{
if (components)
{
delete components;
}
}
System::Windows::Forms::ListViewItem^ files; //my addition
FileInfoContainer compfiles; //my addition
private: System::Windows::Forms::OpenFileDialog^ openFileDialog1;
private: System::Windows::Forms::SaveFileDialog^ saveFileDialog1;
...........
}
This is generated code where I've only added those 2 lines, of which the first works normally while the second gives a member of managed class can't be non-managed class type error.
What can I do to go around this issue?

Why can't I access the private variable of a class after defining a friend function?

I've written a simple employee management project. I am facing problem when I am trying to assign values into the private variables of a class though I defined the operator overloading as friend function.
Here is my code:
#include<iostream>
#include<string>
#include<vector>
#include<fstream>
using namespace std;
class Person
{
string pName;
char pSex;
int pAge;
string pMob;
string pAddress;
public:
Person(){}
Person(string &pn, char &ps, int &pa, string &pm, string &pad):
pName(pn),pAge(pa),pMob(pm),pAddress(pad),pSex(ps){}
string getName(){return pName;}
int getAge(){return pAge;}
string getMob(){return pMob;}
string getAddress(){return pAddress;}
char getSex(){return pSex;}
};
class Employee:public Person
{
string eID;
string eJDate;
string eRank;
double eSalary;
public:
Employee(){}
Employee(string &pn, char &ps, int &pa, string &pm, string &pad, string &eid, string &ejd, string &er, double &es):
Person(pn,ps,pa,pm,pad),eID(eid),eJDate(ejd),eRank(er),eSalary(es){}
string getID(){return eID;}
string getJDate(){return eJDate;}
string getRank(){return eRank;}
double getSalary(){return eSalary;}
friend ostream& operator<<(ostream& os, Employee& ob);
friend istream& operator>>(istream& inf, Employee& ob);
};
ostream& operator<<(ostream& os, Employee& ob)
{
os<<ob.getName()<<endl;
os<<ob.getSex()<<endl;
os<<ob.getAge()<<endl;
os<<ob.getMob()<<endl;
os<<ob.getAddress()<<endl;
os<<ob.getID()<<endl;
os<<ob.getJDate()<<endl;
os<<ob.getRank()<<endl;
os<<ob.getSalary()<<endl;
return os;
}
istream& operator>>(istream& inf, Employee& ob)
{
inf>>ob.pName;
inf>>ob.pSex;
inf>>ob.pAge;
inf>>ob.pMob;
inf>>ob.pAddress;
inf>>ob.eID;
inf>>ob.eJDate;
inf>>ob.eRank;
inf>>ob.eSalary;
return inf;
}
int main()
{
cout<<"\t\t\t\tEnter your choice\n";
cout<<"\t\t\t\t-----------------\n";
cout<<"1: Enter an employee data."<<endl;
cout<<"2: View all the employee data."<<endl;
cout<<"Enter choice: ";
int choice;
cin>>choice;
if(choice==1)
{
string name,mob,address,id,jdate,rank;
int age;
char sex;
double salary;
ofstream out;
out.open("DB.txt",ios_base::app);
cout<<"Enter Name : ";
cin>>name;
cout<<"Enter Sex (M/F): ";
cin>>sex;
cout<<"Enter Age : ";
cin>>age;
cout<<"Enter Mobile No : ";
cin>>mob;
cout<<"Enter Address : ";
getline(cin,address);
cout<<"Enter ID : ";
cin>>id;
cout<<"Enter Join Date (dd-mm-yyyy): ";
cin>>jdate;
cout<<"Enter Position : ";
cin>>rank;
cout<<"Enter Salary : ";
cin>>salary;
Employee ob(name, sex, age, mob, address, id, jdate, rank, salary);
out<<ob;
}
else if(choice==2)
{
ifstream inf("DB.txt");
vector<Employee>ve;
Employee ob;
while(inf>>ob)
{
ve.push_back(ob);
}
for(int i=0; i<ve.size(); i++)
{
cout<<"\nEmployee No - "<<i<<endl;
cout<<"Employee Name: "<<ve[i].getName()<<endl;
cout<<"Sex: "<<ve[i].getSex()<<endl;
cout<<"Age: "<<ve[i].getAge()<<endl;
cout<<"Mobile: "<<ve[i].getMob()<<endl;
cout<<"Address: "<<ve[i].getAddress()<<endl;
cout<<"ID: "<<ve[i].getID()<<endl;
cout<<"Joining Date: "<<ve[i].getJDate()<<endl;
cout<<"Rank: "<<ve[i].getRank()<<endl;
cout<<"Salary: "<<ve[i].getSalary()<<endl;
}
}
return 0;
}
It is giving the following erros-
7|error: ‘std::string Person::pName’ is private|
63|error: within this context|
8|error: ‘char Person::pSex’ is private|
64|error: within this context|
9|error: ‘int Person::pAge’ is private|
65|error: within this context|
10|error: ‘std::string Person::pMob’ is private|
66|error: within this context|
11|error: ‘std::string Person::pAddress’ is private|
67|error: within this context|
||=== Build failed: 10 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Here I can access and assign value to the private variables of Employee class, but can't get access to the private variables of Person class.
Friend function doesn't work here?
How do I code to solve it? How do I load data from file into an object of Employee class?
When you declare a member private in a class it's private for the class itself, even to its children.
So pName in your example is inaccessible from Employee's child class.
If you declare it protected, then the child class can access it (and modify it)
In order to change it in the child class while still keeping the member private, you need to provide accessor (get/set methods) in the parent class. 'setPName' accessor can be public, or protected if you want to limit modification to the Employee class.

How to use references and pointers in c++ classes?

i have the following problem: I am using an existing class which creates an object called server_t.
Another function expects *server_t as an argument.
I wanted to shrink the code and added a class which has following members:
#ifndef _PMCLASS
#define _PMCLASS
#include "pmlib.h"
class pmServer{
private:
server_t server ;
counter_t counter;
line_t lines;
server_t * server2;
int set, frequency, aggregate ;
public:
pmServer();
pmServer(int set, int frequency, int aggregate);
~pmServer();
void setSet(int s);
void setFrequency(int f);
void setAggregate(int a);
int getSet(void);
int getFrequency(void);
int getAggregate(void);
server_t* getServerT(void);
counter_t* getCounterT(void);
line_t* getLineT(void);
server_t* getZeiger(void);
};
#endif
then i created the constructors:
#include "pmClass.h"
#include <iostream>
using namespace std;
void pmServer::setSet(int s){
this->set = s;
}
void pmServer::setFrequency(int f){
this->frequency = f;
}
void pmServer::setAggregate(int a){
this->aggregate = a;
}
int pmServer::getSet(void){
return set;
}
int pmServer::getFrequency(void){
return frequency;
}
int pmServer::getAggregate(void){
return aggregate;
}
server_t* pmServer::getPointer(){
return &server;
}
pmServer::pmServer(){
set = -1;
frequency = 0;
aggregate = 1;
}
then i tried to create an object ->worked, but then i wanted to use the pm_set_server(...)
it wants following arguments: int pm_set_server( char *ip, int port, server_t *pm_server)
void run() {
build_initial_mesh();
// Construct / read in the initial mesh.
pmServer server1;
pm_set_server("xxx.xxx.xxx.xxx", 6526,server1.getPointer); //its a correct ip address , no panic :)
i got that:
error: argument of type 'server_t*' (pmServer::)() does not match 'server_t*'
but this worked without any problems:
void run() {
// Construct / read in the initial mesh.
//pmServer server1;
server_t test;
pm_set_server("xxx.xxx.xxx.xxx", 6526,&test);
build_initial_mesh();
The thing is, i didn't want to create everytime new ojects and wanted to do that in the constructor...Does somebody have any idea?
thanks.
greetings Thomas
In C++, function calls need brackets*:
pm_set_server("xxx.xxx.xxx.xxx", 6526,server1.getPointer());
*exceptions apply, for operators.

banking management code returning junk values (using uml techniques)

my project code on banking doesnt work properly. when i enter the branch and department info as i run (void department) in main .
and i display(void display) them junk values are returned,i think the values are not going in the linked list.
code made in code blocks
part of the code below:
#include<iostream>
#include<conio.h>
#include<cstdio>
#include<string.h>
#include<cstdlib>
#include<malloc.h>
using namespace std;
int code=1100;
int acc=9900;
int loan_no=3300;
int emp=10;
void createmenu();
void depositormenu();
void employee();
void loanmenu();
void operationmenu();
class branch
{
char bname[20];
int bcode;
branch *link;
public:
branch()
{
bcode=code++;
}
void input()
{
fflush(stdin);
cout<<"\nEnter Branch Name: ";
gets(bname);
}
void output()
{
cout<<"\nBranch Name: "<<bname;
cout<<"\tBranch Code: "<<bcode;
}
};
class department
{
char dname[30];
int dcode;
public:
branch *b;
department *link;
department()
{
b=new branch;
}
void input()
{
b->input();
fflush(stdin);
cout<<"Enter Department Code: ";
cin>>dcode;
fflush(stdin);
cout<<"Enter Department Name: ";
gets(dname);
}
void output()
{
b->output();
fflush(stdout);
cout<<"\nDepartment Name: "<<dname;
cout<<"\tDepartment Code: "<<dcode;
}
};
void departments(department **);
void display(department **);
department *start,*p=NULL;
void departments(department **start)
{
department *temp,*r,*temp2;
temp2=*start;
system("cls");
cout<<"\nEnter data for Departments->";
department d;
if(*start==NULL)
{
temp=(department*)malloc(sizeof(department));
d.input();
temp=&d;
temp->link=NULL;
*start=temp;
}
else
{
temp=*start;
while(temp->link!=NULL)
{
temp=temp->link;
}
r=(department*)malloc(sizeof(department));
r->input();
r->link=NULL;
temp->link=r;
}
}
void display(department **start)
{
department *temp;
temp=*start;
fflush(stdout);
if(temp==NULL)
{
cout<<"\nList not created!";
cout<<"\tPress any key to return";
getch();
}
else
{
while(temp)
{
temp->output();
temp=temp->link;
getch();
}
}
}
pls help.
thanks in advance
Since I can't see your input values and expected output values, I can't say for sure. However, since you've opted to using pointers for everything, the one thing I see is with this block of code in the departments function:
department d;
if(*start==NULL)
{
temp=(department*)malloc(sizeof(department));
d.input();
temp=&d; // you are assigning the address of a local variable to temp,
// and then assigning it to the argument pointer.
temp->link=NULL;
*start=temp;
}
If you assign the address of a local variable to an argument pointer and then reference it from outside the function, you will have lost that data.
My suggestion would be to assign the contents of the department to the start object, rather than use the local pointer address.
That is likely why you're seeing garbage data.
I'm surprised the compiler didn't say anything about that.