BAD ACCESS 读入对象后
BAD ACCESS After reading into object
我正在为一个学校项目制作一个密码管理器,它上面贴满了巨大的保修无效标签。目的是能够对程序中的数据进行增删改查,并以"encrypted"的形式写入磁盘。
我有一个基类型和子类型的动态数组,我可以使用 Library::WriteToFiles() 将其写入内存并使用 Library::ReadFromFiles() 从内存中读取。这一切在我的调试设置中都非常有效,我总是写入然后立即读回内存。
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;
}
但是当我注释掉 Write 调用时,我从读取函数中的这个位得到了错误的访问
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();
当我尝试调用密码 class 中的其他非虚拟函数时,它们 运行 就好了。 IsEmpty() 在读取之前也 运行s 就好了。我检查了指针,它始终保持不变。文件正确打开,数据被读入对象。
最让我困惑的是为什么当我已经在那个执行中写入时它仍然有效。如果读入这样的对象会破坏 vtable 那么为什么它有时会起作用?
编辑:
密码 class 有 3 个变量。两个字符串和一个布尔值。没有指针。
这是 public 函数。我只有虚函数有问题。
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();
已经明确这一行:
baseFileObject.read((char*) password, sizeof(*password));
只是不适用于我的用例。序列化是显而易见的、可扩展的、理想的解决方案,但由于这是一个学校项目,我将采用老式的方式将文本写入文件,然后使用 sstream 或类似的东西将其解析回来。
感谢您的帮助:)
我正在为一个学校项目制作一个密码管理器,它上面贴满了巨大的保修无效标签。目的是能够对程序中的数据进行增删改查,并以"encrypted"的形式写入磁盘。
我有一个基类型和子类型的动态数组,我可以使用 Library::WriteToFiles() 将其写入内存并使用 Library::ReadFromFiles() 从内存中读取。这一切在我的调试设置中都非常有效,我总是写入然后立即读回内存。
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;
}
但是当我注释掉 Write 调用时,我从读取函数中的这个位得到了错误的访问
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();
当我尝试调用密码 class 中的其他非虚拟函数时,它们 运行 就好了。 IsEmpty() 在读取之前也 运行s 就好了。我检查了指针,它始终保持不变。文件正确打开,数据被读入对象。
最让我困惑的是为什么当我已经在那个执行中写入时它仍然有效。如果读入这样的对象会破坏 vtable 那么为什么它有时会起作用?
编辑: 密码 class 有 3 个变量。两个字符串和一个布尔值。没有指针。 这是 public 函数。我只有虚函数有问题。
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();
已经明确这一行:
baseFileObject.read((char*) password, sizeof(*password));
只是不适用于我的用例。序列化是显而易见的、可扩展的、理想的解决方案,但由于这是一个学校项目,我将采用老式的方式将文本写入文件,然后使用 sstream 或类似的东西将其解析回来。
感谢您的帮助:)