I am making a password manager for a school project which comes with huge WARRANTY VOID IF USED AT ALL stickers all over it. The aim is to be able to do CRUD on the data in the program and write it to disk in an "encrypted" form.
I have a dynamic array of base and child types which i can write to memory using Library::WriteToFiles() and read from memory using Library::ReadFromFiles(). This all works great in my debug setup where i always write and then immediately read back into memory.
int main() {
bool debug = true;
if (debug) {
Library library = Library();
library.Add(new Password("Outside", "yobro"));
library.Add(new Password("Wut", "idk"));
library.Add(new UsernameLogin("Yo", "M8", "James May"));
library.Print();
cout << endl;
library.WriteToFiles();
library.ReadFromFiles();
library.Print();
return 0;
}
But when i comment out the Write call i get a bad access from this bit in the read function
void Library::ReadFromFiles() {
this->Clear();
ifstream baseFileObject;
ifstream usrNameFileObject;
baseFileObject.open("base.txt");
while (true) {
if (baseFileObject.eof()) break;
Password* password = new Password();
baseFileObject.read((char*) password, sizeof(*password));
if ( ! password->IsEmpty()) { // <- Trying to call IsEmpty() throws a BAD ACCESS
Add(password);
}
}
baseFileObject.close();
When i try calling other functions in the Password class that are not virtual they run just fine. IsEmpty() also runs just fine before the read. I checked the pointer and it stays the same throughout. The files open correctly and the data is read into the object.
What confuses me the most is why it works when i have already written in that execution. If reading into an object like that corrupts the vtable then why does it work sometimes?
EDIT: The password class has 3 variables. Two strings and a bool. No pointers. Here are the public functions. I'm only having problems with the virtual functions.
public:
virtual int Type();
virtual string ToString();
virtual bool IsEmpty();
virtual bool Encrypt(unsigned int key);
virtual bool Decrypt(unsigned int key);
[[nodiscard]] bool isEncrypted() const;
[[nodiscard]] const string &getPassword() const;
void setPassword(const string &newPassword);
[[nodiscard]] const string &getLocation() const;
void setLocation(const string &newLocation);
int PasswordStrength();
It has been made clear that this line:
baseFileObject.read((char*) password, sizeof(*password));
Just doesn't work for my use case. Serialization is the obvious, scalable, ideal solution here but since this is a school project i am going for old fashioned writing text to a file and parsing it back in using sstream or something like that.
Thanks for the help :)