我在AccountManagement.cpp中有一个AccountManagement类。我在Account.cpp中有另一个名为Account的类。我有一个模板,使用OrdereList类对列表中的给定数据进行排序,OrdereList类也有自己的迭代器。 AccountManagement类在二进制文件中输出Accounts列表,如下所示:
void AccountManagement::saveData(const char * file) //saves data in the specified binary file
{
ofstream out(file, ios::out | ios::binary);
if(!out)
{
cerr<<"Problem opening output file!"<<endl;
}
OrderedList<Account>::iterator it = this->account_manager.begin();
for(int i = 0; i < this->total_accounts; i++)
{
Account temp = *it;
out.write((char*)&temp, sizeof(Account));
it++;
}
out.close();
}
我在AccountManagement类中定义了一个以下函数,它从二进制文件中读取所有数据并输出它。这个功能非常好。它显示在这里:
void AccountManagement::output()
{
ifstream in("accounts.dat", ios::in | ios::binary);
if(!in)
{
cerr<<"File doesn't exist!"<<endl;
exit(1);
}
Account acc;
while(in.read((char*)&acc, sizeof(Account)))
{
cout<<acc;
}
in.close();
}
但是,当我在另一个文件中使用同一个函数(具有不同的名称)时,它也有Account.h头文件以从同一个“account.dat”文件中检索数据,这给了我分段错误。可能是什么问题呢?以下是功能:
void loadData()
{
ifstream in("accounts.dat", ios::in | ios::binary);
if(!in)
{
cerr<<"File doesn't exist!"<<endl;
exit(1);
}
Account acc;
while(in.read((char*)&acc, sizeof(Account)))
{
cout<<acc;
}
in.close();
}
帐户的班级声明:
class Account
{
friend ostream& operator<<(ostream&,const Account&); //overloading << operator
friend istream& operator>>(istream&,Account&); //overloading >> operator
public:
void operator=(const Account&); //overloading = operator
bool operator<=(const Account&); //overloading <= operator
bool operator<(const Account&); //overloading < operator
private:
string number; //Account Number
char name[100]; //Account holder's name
char sex; //M or F indicating the gender of account holder
MYLIB::Date dob; //date of birth of account holder
char address[100]; //address of account holder
char balance[20]; //balance of account holder
};
答案 0 :(得分:3)
我不了解MYLIB::Date
课程,但在那里你有一个std::string
对象就足够了。
std::string
对象动态分配内存 以适合它包含的字符串。并且在堆上分配的内存仅对当前进程可用,您不能保存指针(位于std::string
类内)并从其他进程加载它并希望在有效内存时指针。
如果在一个进程中保存指向动态分配的内存的指针,并从另一个进程加载并使用它,那么您将有未定义的行为。
您需要serialize字符串才能保存它。也可能是MYLIB::Data
对象。
免责声明:将在具有单一统一地址映射的小型嵌入式系统上工作,不幸的是,所有面向用户的投标操作系统(如Windows,OSX和Linux)都有单独的地址空间和墙进程之间。
答案 1 :(得分:0)
如果您保存对象并将其再次加载到同一对象和中,那么您的函数AccountManagement::output()
会给出完美的效果,前提是字符串在此期间未发生变化。
出了什么问题?
只要您的对象不再是POD对象(即它包含使用指针的数据,或使用虚函数等等),您只需将其内存写入其中即可保存它。磁盘。
在您的情况下,第二个函数因此失败。第一个功能只给人一种印象。该字符串是一个复杂的对象,它存储指向动态分配的内存的某些指针。如果您编写对象并按原样读取它,而不更改对象,则只需重新读取内存中的值。读取的隐藏指针的值与读取之前的值完全相同。这是一个非常幸运的情况。但在大多数情况下,它会失败。
如何解决?
要保存对象,您应该对其进行序列化:使用适当的函数将每个组件分别写入/重新分配到文件。
最简单的方法是使用一些现有的序列化库,例如 boost serialization 。