Code exiting when Dynamic Array of class allocated - c++

I am trying to dynamically allocate an array and whenever it gets to the part where it dynamically allocates the program exits. I would rather not use vectors as I am trying to learn how to do this using dynamic arrays.
This is the simplified code:
#include <iostream>
#include <string>
using namespace std;
class Student
{
private:
double calcAverage(double* testArray);
char calcGrade(double average);
public:
int nTests, sameTests, idNum;
string name;
double average, *testArray;
char grade;
};
int i;
Student fillStudentArray(int nStudents);
int main()
{
*studentArray = fillStudentArray(nStudents);
return 0;
}
Student fillStudentArray(int nStudents)
{
Student *newStudentArray = new Student[nStudents];
cout << "If you can see this I worked. ";
delete[] studentArray;
return *newStudentArray;
}
I have tried the solution posted here Creation of Dynamic Array of Dynamic Objects in C++ but it also exits in a similar way. The main for the code looks like this.
int main()
{
int nStudents = 3; //this number is just for testing, in actual code it has user input
Student** studentArray = new Student*[nStudents];
cout << "1 ";
for(i = 0; i < nStudents; i++)
{
cout << "2 ";
studentArray[i] = new Student[25];
cout << "3 ";
}
return 0;
}

close (heres a cigar anyway)
Student* fillStudentArray(int nStudents); <<== function must return pointer to students
int main()
{
int nStudents = 3; <<<=== declared nstudents
Student *studentArray = fillStudentArray(nStudents); <<< declare studentArray
return 0;
}
Student *fillStudentArray(int nStudents) <<<== return pointer
{
Student* newStudentArray = new Student[nStudents];
cout << "If you can see this I worked. ";
// delete[] studentArray; <<<== what were you trying to delete?
return newStudentArray; <<<=== return pointer
}
the second code you showed is not relevant, its creating a 2d array

Related

Through what to call the method, if I already created constructor with initialization of array of structures?

I'm trying to call the method displayChoices, member of the class MachineManager through the object of the class. But I already have a constructor with initializing of the array of structures. How I understood when we create an object of the class compiler implicitly create a default constructor of the class.
Question: How to call method displayChoices?
#include "MachineManager.h"
using namespace std;
int main()
{
MachineManager mjp;
mjp.displayChoices();
return 0;
}
struct BrewInfo {
string* DrinkName;
double* Cost;
int* Number;
};
class MachineManager {
static const int Num_Drinks = 3; /// why it works only with static?!!!
BrewInfo* BrewArr[Num_Drinks];
public:
MachineManager()
{
*BrewArr[0]->Cost = 1.25;
*BrewArr[0]->Number = 20;
*BrewArr[1]->DrinkName = "pepsi";
*BrewArr[1]->Cost = 1.15;
*BrewArr[1]->Number = 17;
*BrewArr[2]->DrinkName = "Aloe";
*BrewArr[2]->Cost = 2.00;
*BrewArr[2]->Number = 15;
};
int displayChoices();
}
int MachineManager::displayChoices() // (which displays a menu of drink names and prices)
{
cout << 1;
int choice;
cout << "|1." << *BrewArr[0]->DrinkName << " |2." << *BrewArr[1]->DrinkName << " |3." << *BrewArr[2]->DrinkName << " |" << endl;
cin >> choice;
if (!choice || choice == 0) {
system("slc");
displayChoices();
}
else
return choice;
}
displayChoices has to print a menu in console.
You have a majo bug in your source code. You do not yet understand, how pointer work.
You are defining an array of pointer with BrewInfo* BrewArr[Num_Drinks];.
But these pointers are not initialized. They point to somewhere. Then you are dereferencing those pointers (pointing to somewhere) and assigning a value to somewhere in the memory.
This is a major bug.
The array dimensions for C-Sytle arrays must be a compile time constant.
You cannot write
int x=3;
unt array[x];
This is C99 code (called VLA, Variable length array), but not C++.
Solution for you problem:
Do never use C-Style arrays, like int array[5]. Use STL container like std::vector instead.
Do not use pointers.
This is your major problem. Define your array with BrewInfo BrewArr[Num_Drinks];. Please remove also the pointer from
struct BrewInfo {
string* DrinkName;
double* Cost;
int* Number;
};

Nested structure function in c++

I'm having trouble with one of my assignments (or maybe I'm overthinking it?)
I need to create
a function to take integer parameters for number of students and tests.
Allocate the memory needed for the array of students and the array of test scores for each student.
Return a pointer to the array of Student structures. No display output is done in this function.
int main()
{
int studentNum;
int testNum;
cout << "How many students are there?\n";
cin >> studentNum;
cout << "How many tests are there?";
cin >> testNum;
system("pause");
return 0;
}
my function
GradeBook *initArrays(int s, int t)
{
GradeBook *ptr;
// Allocate the array of Student structures.
ptr = new GradeBook[s];
// Allocate an array of ints (to hold test scores)
// for each element of the array of Student structures.
for (int count = 0; count < s; count++)
{
ptr[count].tests = new int[t];
}
// Return a pointer to the array of structures.
return ptr;
}
edit: I have edited my function, could i get some opinions on that?
if you are writing this in c++, use classes. if i understand correctly, you should create a structure to save a students id,name,or something and a corresponding grade?
something like:
class Test{
public:
int id;
int grade;
Test(int id, int grade){
this->id = id;
this->grade = grade;
}
};
class Student{
public:
int id;
std::string name;
std::vector<Test> tests;
Student(int id, std::string name)
{
this->id = id;
this->name = name;
}
};
int main(){
vector<Student> students;
int studentnum;
for (int i = 0; i < studentnum; i++){
students.push_back(Student(i, "name"));
//insert all tests of the student by calling students[i].tests.push_back(Test(id, grade))
}
}
this way you don't have to allocate memory, which you can easily overlook freeing.
edit:
this is very basic and not a sophisticated solution, as the properties of the classes are all public.
edit 2:
typedef struct Test{
int id;
int grade;
}Test;
typedef struct Student{
int id;
std::string name;
Test * tests;
}Student;
int main(){
Student * students;
int studentnum;
students = (Student*)malloc(sizeof(Student)*studentnum);
for (int i = 0; i < studentnum; i++){
students[i]->id = id;
students[i]->name = "name";
student[i]->tests = (Test*)malloc(sizeof(Test)*numberofgradesofthatstudent);
for (int j = 0; j < numberofgradesofthatstudent; j++)
{
students[i]->tests[j]->id = testid;
students[i]->tests[j]->grade = grade;
}
}
}
this is schematic! new and malloc reserve memory on the heap, do not forget to free everything when you are done with it.
As said a little above, be careful using brackets {} to delimit your blocks.
Secondly,the syntax:
array[studIndex].Tests
supposes that the value array[studIndex] (here an integer) has a member value named Tests. But in this case it doesn't.
Think about your problem: you need to store two values "connected" to one another in a static array. The way I see it, you should try on with two dimensional arrays:
int 2dArray[nbStudents][nbTests];
If you don't want to bother with 2dimensional arrays, you can also try
int 2dArray[nbStudents * nbTests];
But for conveniance, it is often better to use 2d arrays.
Also, think about declaring your array before the for loops in your function.
Then concatenate two for loops as you did and I'll let you think about the rest...

c++ segmentation fault for dynamic arrays

I want to add a theater object into a boxoffice object in a C++ code. When I try to add it in main code, first one is added successfully. But a segmentation fault occurs for second and obvioulsy other theater objects. Here is the add function;
#include <iostream>
#include <string>
#include "BoxOffice.h"
using namespace std;
BoxOffice::BoxOffice()
{
sizeReserv = 0;
sizeTheater = 0;
theaters = new Theater[sizeTheater];
reserv = new Reservation[sizeReserv];
}
BoxOffice::~BoxOffice(){}
void BoxOffice::addTheater(int theaterId, string movieName, int numRows, int numSeatsPerRow){
bool theaterExist = false;
for(int i=0; i<sizeTheater; i++)
{
if(theaters[i].id == theaterId)
{
theaterExist=true;
}
}
if(theaterExist)
cout<<"Theater "<<theaterId<<"("<<movieName<<") already exists"<< endl;
else
{
++sizeTheater;
Theater *tempTheater = new Theater[sizeTheater];
if((sizeTheater > 1)){
tempTheater = theaters;
}
tempTheater[sizeTheater-1] = Theater(theaterId,movieName,numRows,numSeatsPerRow);
delete[] theaters;
theaters = tempTheater;
cout<<"Theater "<<theaterId<<"("<<movieName<<") has been added"<< endl;
cout<<endl;
delete[] tempTheater;
}
}
And I get segmentation fault on this line;
tempTheater[sizeTheater-1] = Theater(theaterId,movieName,numRows,numSeatsPerRow);
This is Theater cpp;
#include "Theater.h"
using namespace std;
Theater::Theater(){
id=0;
movieName="";
numRows=0;
numSeatsPerRow=0;
}
Theater::Theater(int TheaterId, string TheaterMovieName, int TheaterNumOfRows, int TheaterNumSeatsPerRow)
{
id = TheaterId;
movieName = TheaterMovieName;
numRows = TheaterNumOfRows;
numSeatsPerRow = TheaterNumSeatsPerRow;
theaterArray = new int*[TheaterNumOfRows];
for(int i=0;i<TheaterNumOfRows;i++)
theaterArray[i]= new int[TheaterNumSeatsPerRow];
for(int i=0; i<TheaterNumOfRows;i++){
for(int j=0;j<TheaterNumSeatsPerRow;j++){
theaterArray[i][j]=0;
}
}
}
This is header file of Theater;
#include <iostream>
#include <string>
using namespace std;
class Theater{
public:
int id;
string movieName;
int numRows;
int numSeatsPerRow;
int **theaterArray;
Theater();
Theater(int TheaterId, string TheaterMovieName, int TheaterNumOfRows, int TheaterNumSeatsPerRow);
};
And this is how i call add functions;
BoxOffice R;
R.addTheater(10425, "Ted", 4, 3);
R.addTheater(8234, "Cloud Atlas", 8, 3);
R.addTheater(9176, "Hope Springs",6,2);
The problematic lines are these:
if((sizeTheater > 1)){
tempTheater = theaters;
}
First you allocate memory and assign it to tempTheater, but here you overwrite that pointer so it will point to the old memory. It does not copy the memory. Since the code is for a homework assignment, I'll leave it up to you how to copy the data, but I do hope you follow the rule of three for the Theater class (as for the BoxOffice class) which will make it very simple.
Also, there's no need to allocate a zero-size "array", just make the pointers be nullptr (or 0).

C++ "No matching constructor for initializing Employee"

I am new to C++ and practicing using vector as an object. However, I got an error "No matching constructor for initializing Employee" when I tried running the following program.
Please tell me how I could modify my program!
Also, when I write
staff[0] = Employee{"Harry Potter" 55000};
does this mean that I am storing string and double data in one of 10 open boxes in vector object of type Employee?
I apologize for such a basic question.
Thank you so much in advance!!
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Employee
{
public:
Employee(string, double);
double get_salaries();
string get_name();
void set_salaries(double);
private:
string name;
double salaries;
};
Employee::Employee(string n, double s)
{
name = n;
salaries = s;
}
double Employee::get_salaries()
{
return salaries;
}
string Employee::get_name()
{
return name;
}
void Employee::set_salaries(double s)
{
salaries = s;
}
int main()
{
// using vector as an object
int i;
vector<Employee> staff(10);
staff[0] = Employee{"Harry Potter", 55000};
if (staff[i].get_salaries() < 100000)
cout << staff[i].get_salaries();
return 0;
}
Your Employee class does not have a default, parameterless, constructor.
When you create the staff vector, it will create 10 Employee objects, thus invoking the default constructor.
To support this,
vector<Employee> staff(10);
you have to provide default constructor in your class.
Your main method
int main()
{
// using vector as an object
int i; // [i] not initialized anywhere.
vector<Employee> staff(10); // Incorrect way of declaring a vector
staff[0] = Employee{"Harry Potter", 55000}; // Incorrect way of creating a instance of class
if (staff[i].get_salaries() < 100000)
cout << staff[i].get_salaries();
return 0;
}
Change your main method like this
int main()
{
vector<Employee> staff;
staff.push_back(Employee("Harry Potter", 55000));
if (staff[0].get_salaries() < 100000)
cout << staff[0].get_salaries();
return 0;
}

Program Crashes While Setting Data in Array

I'm working on a project and every time I go to set example[4].m_dArray[3], the program crashes. I can set the value of every other variable up until I get to example[4].m_dArray[3]. Any help would be appreciated!
Prog1Class.h:
#include "Prog1Struct.h"
#pragma once
#include <iostream>
#include <string.h>
using namespace std;
class Prog1Class
{
private:
Prog1Struct example[4];
public:
Prog1Class();
~Prog1Class ();
void setStructData();
void getStructData();
void ptrFunction();
void refFunction();
void printStruct();
void printData();
};
Prog1Struct.h:
#pragma once
#include <string.h>
struct Prog1Struct {
int m_iVal;
double m_dArray[4];
char m_sLine[80];
};
Prog1Class.cpp:
#include "Prog1Class.h"
#include "Prog1Struct.h"
#include <iostream>
#include <string.h>
using namespace std;
Prog1Class::Prog1Class()
{
}
Prog1Class::~Prog1Class()
{
delete &example[4];
}
int main()
{
Prog1Class *aClass = new Prog1Class();
aClass->setStructData();
aClass->printData();
return 0;
}
void Prog1Class::setStructData()
{
for(int i=0;i<5;i++)
{
cout << "Enter an integer: ";
cin >> example[i].m_iVal;
for(int j=0;j<5;j++)
{
cout << endl << "Enter a double: ";
cin >> example[i].m_dArray[j];
}
cout << endl << "Enter a string: ";
cin.ignore(256,'\n');
cin.getline(example[i].m_sLine, 80, '\n');
cout << endl;
}
}
void Prog1Class::getStructData()
{
}
void Prog1Class::printData()
{
for(int i=0;i<5;i++)
{
cout << example[i].m_iVal;
for(int j=0;j<5;j++)
{
cout << example[i].m_dArray[j];
}
cout << example[i].m_sLine;
}
}
You need to change this
class Prog1Class
{
private:
Prog1Struct example[4];
to this
class Prog1Class
{
private:
Prog1Struct example[5];
In C++ arrays start at index 0, so an array of size 4 has valid indexes 0 upto 3. You're using example[4] so you need an array of (at least) size 5.
You also need to remove delete &example[4]; from your destructor as well.
First , delete &example[4]; should be delete [] example;
Second, where did you allocate memory for example?
You need to show the way the example object is declared? I'd suspect some mis-allocated or mis-declared problem with it. Your setStructureData doesn't do anything ostensibly wrong (assuming the array sizes match and the size of the string is fitting - it is a char array, not a pointer, correct?).
for (int i = 0; i < 5; i++)
// ^^^^^
Your for loops should have an ending condition with i < 4 since your arrays have only 4 spaces. Moreover, your delete should be delete[] example;.
Array deletion is delete [] example, not your way. Also, to use delete data needs to be allocated with new
Here is small example how to use new and delete
#include <iostream>
struct foo
{
foo() {std::cout <<"constructed\n";}
~foo() {std::cout <<"destroyed\n";}
};
int main ()
{
foo * pt;
pt = new foo[3];
delete[] pt;
return 0;
}
Also the output:
constructed
constructed
constructed
destroyed
destroyed
destroyed
I gave a lesson about new/delete and just now seen real problem:
example[4] is out of bounds. If you declare array with 4 elements it means you have indexes 0, 1, 2, 3 and nothing more.