I'm doing an university project on a library.
The class Book
is used on data so I thought of creating a vector with pointers to the objects Book
's. The problem is, I need to read an input file with the data and then create a Book
to add to the vector<Book*>
catalog.
Whenever I do so, the getline()
with integers works fine, but as soon as I try to save a string data to the Book
, such as Title
, I get a total different string of characters instead of the desirable title, or worse, an error.
#ifndef LIBRARY_PROGRAM_BOOK_H
#define LIBRARY_PROGRAM_BOOK_H
#include <iostream>
#include <vector>
#include <string>
#include "Person.h"
class Book
{
public:
//Book(std::string title, int id, );
Book() {};
~Book(){};
void setTitle(std::string title);
std::string getTitle() const;
void setBookId(int bookId);
int getBookId() const;
void setOwner(int owner);
int getOwner() const;
void setCategory(std::string category);
std::string getCategory() const;
void setValue(float value);
float getValue() const;
void setLoanFee(float loanFee);
float getLoanFee() const;
void setIsBorrowed(bool isBorrowed);
bool getIsBorrowed() const;
void setBeginOfLoan(int beginOfLoan);
int getBeginOfLoan() const;
void setMaximumLoanTime(int maximumLoanTime);
int getMaximumLoanTime() const;
void setEndOfLoan(int EndOfLoan);
int getEndOfLoan() const;
int getLoanTimeRemaining() const;
void addRating(float rating);
float getRating() const;
void addComment(std::string comment);
std::vector<std::string> getComments() const;
//void addToWaitingList(Person* person);
//bool removeFromWaitingList(Person* person);
//void sortWaitingList();
private:
std::string title; /**Book title*/
int bookId; /**Book id*/
int owner; /**Id from the book owner*/
std::string category; /**Book category, i.e. Fiction, Drama, Police, ...*/
float value; /**Book value*/
float loanFee; /** Book loan fee*/
bool isBorrowed; /** Boolean variable containing if the book is borrowed or not, true if yes, no otherwise*/
int beginOfLoan; /**Will be set to 0 if book is not loaned in the moment */
int maximumLoanTime; /**Max time that a book should be loaned, should be defined by the book owner*/
int endOfLoan; /**Will be set to 0 if book is not loaned in the moment */
std::vector<float> ratings; /**Vector containing all the ratings given by the readers*/
std::vector<std::string> comments; /**Vector containing all the comments given by the readers*/
//std::vector<Person*> waitingList; /**Vector containing who is waiting to read the book*/
bool isLost; /** Boolean variable containing if the book is lost or not, true if yes, no otherwise*/
};
#endif //LIBRARY_PROGRAM_BOOK_H
This is the code where I read the file, create a Book
, and add it to the catalog:
std::ifstream books_file ("../Books.txt");
// adding books to the catalog
while(!books_file.eof()) {
Book book;
std::getline(books_file, input);
if(books_file.eof()) break;
book.setTitle(input);
std::getline(books_file, input);
book.setBookId(std::stoi(input));
std::getline(books_file, input);
book.setOwner(std::stoi(input));
catalog.push_back(&book);
}
books_file.close();
Does it have to do with the way I'm using pointers?
I tried doing vector<Book>
instead of vector<Book*>
and it works perfectly.
What am I not seeing right?
EDIT: error on Clion:
Process finished with exit code -1073741819 (0xC0000005)
while(!books_file.eof()) {
Book book; <--------- stack allocated variable
std::getline(books_file, input);
if(books_file.eof()) break;
book.setTitle(input);
std::getline(books_file, input);
book.setBookId(std::stoi(input));
std::getline(books_file, input);
book.setOwner(std::stoi(input));
catalog.push_back(&book); <------- take address of stack allocation
} <----------- destroy stack allocation, making the address invalid
Solutions
make the vector contain books instead of pointers, if the vector is huge you will get hit by some copying/moving.
make a heap allocated copy of the book.
untested code
std::vector<std::unique_ptr<Book>> catalog.
auto book = std::make_unique<Book>(/* insert data for constructor of Book */);
catalog.emplace_back(std::move(book));
Using unique_ptr so the books gets destroyed when catalog does.
I think the root of your issue is that you create a Book
right below the while
line, take it's address when you put it in the vector, but then that Book
immediately goes out of scope when you hit the }
so it's destroyed and the pointer is pointing at essentially random memory. If you want to store a pointer to it you should allocate it on the heap via Book* book = new Book;
. But as others have pointed out, you'd probably be better off storing the Book
itself or a unique_ptr<Book>
in your vector
instead of raw pointers.
User contributions licensed under CC BY-SA 3.0