I am trying to dynamically allocate an array of records. When I run my program with ./a.out it appears to work fine but when I try and run the program inputing the data from a .txt file (./myProg < ) it repeatedly records the first line of text in the whole array and crashes and does not print out the chosen book in the end. My guess is I am not creating the array properly but I cannot seem to figure out what my problem is.
struct Book {
char *title; //entered with no spaces
int date; // in the form ddmmyy
};
Book *createRecord(int);
void input(Book *, int);
void display(Book *, int, int);
void destroyRecord(Book *);
int main() {
int arrN = 0;
int n = 0;
cout << "Enter size of array: ";
cin >> arrN;
Book *bookArr;
bookArr = new Book[arrN];
bookArr = createRecord(arrN);
input(bookArr, arrN);
cin.ignore();
cout << "Book: ";
cin >> n;
display(bookArr, arrN, n);
destroyRecord(bookArr);
return EXIT_SUCCESS;
}
Book *createRecord(int arrN){
struct Book *bookArr;
bookArr = new Book[arrN];
return bookArr;
}
void input(Book *bookArr, int arrN) {
for(int i = 0; i < arrN; i++){
char arrFirst[20];
cin.ignore();
cout << "Name: ";
cin.getline(arrFirst, 20);
strcpy((bookArr[i]).title = new char, arrFirst);
cout << "Score: ";
cin >> (bookArr[i]).date;
}
}
void display(Book *bookArr, int arrN, int n) {
if (0 <= n && n <= arrN){
cout << (bookArr[n-1]).title << " " << (bookArr[n-1]).date << endl;
}
}
void destroyRecord(Book *bookArr) {
delete [] (bookArr)->title;
delete bookArr;
}
Well, first up, you're allocating two arrays:
bookArr = new Book[arrN]; // <-- leaked
bookArr = createRecord(arrN);
That's a memory leak.
Secondly:
(bookArr[i]).title = new char
That is allocating one single char that you're trying to copy a whole string into. That should probably be:
// two lines please!
bookArr[i].title = new char[20];
strcpy(bookArr[i].title, arrFirst);
Thirdly:
if (0 <= n && n <= arrN){
That bounds check is incorrect. The upper bound should be n < arrN
, and then just index n
. By indexing n - 1
, you might print the -1st index.
And last, but not least, prefer:
struct Book {
std::string title;
int date;
}
std::vector<Book> bookArr;