c++ segmentation fault for dynamic arrays - c++

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).

Related

Code exiting when Dynamic Array of class allocated

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

sort array of objects alphabetically c++

I am enrolled in an Object Oriented programming class and am using code::blocks as my IDE. We have a project that requires to pass an array of objects ( a Libray book array with private names and titles) into a sort array that will sort the titles or authors alphabetically. I have all the components working as they should be except the sort function. I used a sort function that I have used before in other programs but am having trouble getting it to work with this program. I am still in the beginning stages of learning how to code and would appreciate any feedback.
Header file:
#include <iostream>
#include <cstring>
using namespace std;
class Book
{
private:
string title;
string author;
public:
Book();
string getTitle();
string getAuthor();
void setTitle(string Title1);
void setAuthor(string Author1);
};
Main:
#include <iostream>
#include <cstring>
#include <iomanip>
#include "Library.h"
using namespace std;
//Sort function prototype
void s_sort (Book lib_books[], int n);
int main()
{
// Initializes n as the number of books
int n = 15;
//Declaration of array of objects
Book lib_books[15];
// Declartion of the private member "title" for each object
lib_books[0].setTitle("The Alchemist");
lib_books[1].setTitle("The Princess Bride");
lib_books[2].setTitle("The Catcher in the Rye");
lib_books[3].setTitle("1984");
lib_books[4].setTitle("Fahrenheit 451");
lib_books[5].setTitle("The Great Gatsby");
lib_books[6].setTitle("Poland");
lib_books[7].setTitle("The Cantebury Tales");
lib_books[8].setTitle("Leaves of Grass");
lib_books[9].setTitle("Where the Sidewalk Ends");
lib_books[10].setTitle("The Iliad");
lib_books[11].setTitle("Things to Think On");
lib_books[12].setTitle("The Grapes of Wraith");
lib_books[13].setTitle("Hop on Pop");
lib_books[14].setTitle("The Prince and the Pauper");
// Declartion of the private member "author" for each object
lib_books[0].setAuthor ("Paulo Coalho");
lib_books[1].setAuthor ("William Goldman");
lib_books[2].setAuthor ("J.D. Salinger");
lib_books[3].setAuthor ("George Orwell");
lib_books[4].setAuthor ("Ray Bradbury");
lib_books[5].setAuthor ("F. Scott Fitzgerald");
lib_books[6].setAuthor ("James A. Mitchener");
lib_books[7].setAuthor ("Chaucer");
lib_books[8].setAuthor ("Walt Whitman");
lib_books[9].setAuthor ("Shel Silverstein");
lib_books[10].setAuthor("Homer");
lib_books[11].setAuthor("Krishnamurti");
lib_books[12].setAuthor("John Steinbeck");
lib_books[13].setAuthor("Dr. Seuss");
lib_books[14].setAuthor("Mark Twain");
The portion of main that I'm having issues:
// Function to sort the books alphabetically by author
s_sort (lib_books,n);
cout << "\n";
// For loop to print all 15 books with author and title
for(int i = 0; i < 14; i++)
{
cout <<" "<<setw(25)<<lib_books[i].getTitle()<< " " <<lib_books[i].getTitle()<< "\n" ;
}
return 0;
}
//Sort function definition
void s_sort (Book::getTitle(), int n)
{
int m;
string hold;// Initializes 'hold' as a 'string' so all the characters will be used when it is sorted
for (int k=0; k<=n-1; k++)// 'For' loop sorts through the index
{
m = k;
for (int j=k+1; j <= n-1; j++)
{
if (lib_books[j].getTitle() < lib_books[m].getTitle());
//m = j;
}
// Swaps the lib_book[].getTitle() around and uses 'hold' as a placement
hold = lib_books[m].getTitle();
lib_books[m].getTitle() = lib_books[k].getTitle();
lib_books[k].getTitle() = hold;
hold = lib_books[m].getAuthor();
lib_books[m].getAuthor() = lib_books[k].getAuthor();
lib_books[k].getAuthor() = hold;
}
}
Implementation file:
#include <iostream>
#include <cstring>
#include "Library.h"
using namespace std;
Book::Book()
{
title = " ";
author = " ";
}
string Book::getTitle()
{
return title;
}
string Book::getAuthor()
{
return author;
}
void Book::setTitle(string Title1)
{
title= Title1;
}
void Book::setAuthor(string Author1)
{
author= Author1;
}
The problem that I am having is that it doesn't sort the array. It prints out the same list that was defined. I have tried to pass the array by reference but it needs a index number in the function prototype and definition.

C++ Dynamic Array: A value of type "void" cannot be used to initialize an entity of type "int"

I am working on a C++ project for school in which the program will read in a list of numbers from a text file, store them in a dynamic array, then print them out to another text file. To be honest I'm a little lost with the pointers in this, and I am getting the error "A value of type "void" cannot be used to initialize an entity of type "int"" in my main source file.
Main.cpp (this is where I'm getting the error):
#include "dynamic.h"
int main
{
readDynamicData("input.txt","output.txt");
}
dynamic.cpp (the skeleton for the program):
#include "dynamic.h"
void readDynamicData(string input, string output)
{
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
int *temp = da.theArray;
da.theArray = new int[da.size];
ifstream in(input);
ofstream out(output);
in >> da.number; //prime read
while (!in.fail())
{
if (da.count < da.size)
{
da.theArray[da.count] = da.number;
da.count++;
in >> da.number; //reprime
}
else grow; //if there are more numbers than the array size, grow the array
}
out << "Size: " << da.size << endl;
out << "Count: " << da.count << endl;
out << "Data:" << endl;
for (int i = 0; i < da.size; i++)
out << da.theArray[i];
in.close();
out.close();
delete[] temp;
}
void grow(DynamicArray &da) //this portion was given to us
{
int *temp = da.theArray;
da.theArray = new int[da.size * 2];
for (int i = 0; i<da.size; i++)
da.theArray[i] = temp[i];
delete[] temp;
da.size = da.size * 2;
}
and dynamic.h, the header file:
#include <iostream>
#include <string>
#include <fstream>
#ifndef _DynamicArray_
#define _DynamicArray_
using namespace std;
void readDynamicData(string input, string output);
struct DynamicArray
{
int *theArray;
int count;
int size;
int number;
};
void grow(DynamicArray &da);
#endif
you have to add parenthesis to main or any function:
int main(){/*your code here ...*/};
2- you are using an unitialized objct:
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
so int* theArray is a member data and is uninitialized so welcome to a segfault
all the members of da are not initialized so you have to do before using it.
3- also you add parenthesis to grow function:
else grow(/*some parameter here*/); // grow is a function
4- using namespace std; in a header file is a very bad practice.
tip use it inside source
5- why making inclusion of iostream and string.. before the inclusion guard??
correct it to:
#ifndef _DynamicArray_
#define _DynamicArray_
#include <iostream>
#include <string>
#include <fstream>
/*your code here*/
#endif
main is a function so it needs brackets:
int main(){
// your code
return 0; // because it should return intiger
}
And. Your grow is also a function, so if you want to call it you write grow() and it needs DynamicArray as a parameter.
It is impossible to write working programs on C/C++ any programming language not knowing a basic syntax.

dynamically allocate memory to struct array c++

let me start by saying I know this is a funky way to program, but my teacher is requiring us to go about it this way.
also:
I CANT use std::string, classes, constructors for this project.
I am required to use this archaic method of c-style strings with dynamic memory allocation occuring outside the struct.. i know its not the best way to go about this, but theres nothign i can go. :(
Im stuck with the structs, I cant figure out whats wrong..
I have a struct
#include <iostream>
#include <fstream>
#include <ctime>
#include <stdlib.h>
#include <string>
using namespace std;
//global constant(s)
const int maxCards = 52;
//Structs
struct card
{
char *suit;
char *rank;
int cvalue;
char location;
};
//Function List
void readPlayers(player *peoplePointer);
void shuffleCards(card *unshuffled, card* shuffled);
//program
int main()
{
//create pointer and set initial value
card * deckPointer = new card[52];
card *deckHome = &deckPointer[0];
for(int i=0;i<maxCards;i++)
{
(*deckPointer).suit=new char[8];
(*deckPointer).rank = new char[7];
deckPointer++;
}
deckPointer = deckHome;
cardInit(deckPointer);
readDeck(deckPointer);
//sets default values for the card arrays
for(int i=0;i<52;i++)
{
strcopy((*deckPointer).suit,"suit");
strcopy((*deckPointer).rank,"rank");
(*deckPointer).cvalue = 0;
deckPointer++;
}
deckPointer = deckHome;
return 0;
}
//Functions
void cardInit(card *deckPointer)
{
card * deckHome = NULL;
deckHome = &deckPointer[0];
//set up card file to be read in
ifstream fin;
char *finName = new char[13];
//get file name from user
cout << "Enter file name...(cardFile.txt)" << endl;;
cin >> *finName;
//open the file
fin.open(finName);
//check if cardFile.txt opens correctly
if(!fin.good())
{
cout << "Error with card file" << endl;
}
else
{
deckPointer = deckHome;
while(fin.good())
{
for(int i=0;i<50;i++)
{
fin >> (*deckPointer).suit;
fin >> (*deckPointer).rank;
fin >> (*deckPointer).cvalue;
deckPointer++;
}
}
}
delete [] finName;
}
//Its a pretty simple program..and my dynamic memory works for
//the file name, but I cant figure out why it doesnt work for structs?
For your code to work, you will need a typename card.
to this end you will need to setup the following:
struct cardstruct {
char *suit;
char *rank;
int cvalue;
};
typedef struct cardstruct card;
otherwise, when you declare the pointers, you would need to use the "struct" keword first. E.G.:
struct card *deckPtr = new struct card[52];

C++ code pass compling but return Segmentation fault

I have the following C++ code for practising sequence list and it passed the complier. However, when I try to run it, it returns Segmentation fault. Please help!! Thanks a lot.
main.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
int main() {
SeqList seq;
string vv[] = {"a", "b", "c", "d"};
for (int i = 0; i< 4; i++) {
seq.addElement(vv[i], i);
}
string* v = seq.getSeq();
for (int i=0; i<seq.getSeqSize(); i++) {
cout << v[i] <<endl;
}
return 0;
}
SeqList.h
#include<iostream>
#include<string>
using namespace std;
class SeqList {
private:
string seq[];
int size;
public:
void addElement(string, int);
void delElement(string, int);
string* getSeq();
int getSeqSize();
};
SeqList.cpp
#include <iostream>
#include <string>
#include "SeqList.h"
using namespace std;
string seq[100];
int size = 0;
string* SeqList::getSeq(){
return seq;
};
int SeqList::getSeqSize(){
return size;
};
void SeqList::addElement(string str, int pos) {
int i;
for (i = size; i > pos; i--) {
seq[i] = seq[i-1];
}
seq[i-1] = str;
size++;
};
Your segfault is happening because you're trying to access seq[i-1] in addElement when i = 0. This tries to access the memory outside of seq which causes a segfault. Try using seq[i] and seq[i+1] instead of seq[i-1] and seq[i], though you'll have to make sure you never call that code with more than 99 values or you'll run into a similar problem where the program tries to access memory past the end of seq.
Also, in SeqList.cpp
string seq[100];
int size = 0;
These lines are creating new variables, when it looks like you're trying to change the values you made in SeqList.h. To change those private values in your class you should either use a constructor or other function to initialize the values.