无法读取Ubuntu中的.dat或.bin文件“Segmentation fault(核心转储)”
因此,我刚刚开始使用Ubuntu。 我正在构建这个非常简单的程序,它可以让我存储一些数据并在稍后读回。无法读取Ubuntu中的.dat或.bin文件“Segmentation fault(核心转储)”
使用C++,fstream,一些对象存储在.dat文件中。
// function to store
void storeRecord(Record r){
fstream afile;
afile.open("file.dat" , ios::out | ios::binary | ios::app);
afile.write(reinterpret_cast <const char*> (&r), sizeof(r));
afile.close();
}
但当我尝试(调用查询()函数)从同一个文件中读取,我得到“分割故障(核心转储)”
void query(){
Record r;
fstream afile;
afile.open("file.dat", ios::in | ios::binary);
while(afile.read(reinterpret_cast <char*> (&r), sizeof(r))){
// do something
}
afile.close();
}
这用来工作在窗户上。这是为什么?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Record{
public:
// Constructors
Record();
Record(string accountID, string name, string deptID, string password, int role);
~Record();
// Assessors and Mutators
string getAccountID();
string getName();
string getDeptID();
string getPW();
int getRole();
void setAccountID(string accountID);
void setName(string name);
void setDeptID(string deptID);
void setPW(string PW);
void setRole(int role);
// Other functions
string toString();
private:
string accountID;
string name;
string deptID;
string password;
int role; // normal user, HR personal, admin
};
您的Record
包含std::string
字段。
A string
当然包含指针,并可能包含一些带有虚函数的内部数据(因此有一个vtable,这是一个隐藏的指针);那么这些数据就有了指针。并且string
是而不是 a POD(但是固定阵列的char
将是例如像char name[48];
....的字段)。
所以,你的代码有undefined behavior所以你是幸运的,它crashes在Linux(和倒霉说,“出现”,它在Windows上工作)......顺便说一句,当它是显然“运行”(例如上您的Windows)文件格式保持“未定义”,您将无法再读取由旧版本程序编写的数据文件(或甚至是由较旧或不同的编译器和C++标准库编译的相同源文件)。
Linux有ASLR;这可能可以解释为什么你有一个segmentation fault。顺便说一句,我猜测,如果您在相同的process(这对您不是特别有用)中编写和读取相同的数据文件,Linux可能不会崩溃。
要了解更多信息,您需要深入了解实施细节,而您不想。
显然,您需要实施一些serialization机械。然后指定首先(详细)你的file format(逐字节,endianness和“字大小”的问题和你的文件格式应该是“独立”的),也许使用一些EBNF表示法。然后执行序列化例程,从基本POD类型开始。或者使用一些序列化库。你的文件格式和代码应该是可移植的(例如,树莓派和Linux/PC上的相同程序应该能够交换数据文件)。
顺便说一句,我更喜欢使用一些文本格式,可能使用JSON,YAML(或XML)。或者考虑像SQLite或GDBM这样的库。在你的情况下,你的Record
很容易映射到SQLite表中的行或JSON对象。也许你应该问你的老师是否允许使用它们......
在查询中没有定义r。什么是记录?如果它不是POD,那么你有bug。 – 2017-10-17 17:39:44
有。在实际的程序中。我的错误在这里。 oops – poh
“Record”的类型是什么?它是否有一些[vtable](https://en.wikipedia.org/wiki/Virtual_method_table)或一些(甚至是不正确的或内部的)指针? **你的代码有[未定义的行为](https://en.wikipedia.org/wiki/Undefined_behavior)**,所以你很幸运,它在Linux上崩溃(并且*不幸*它出现在Windows上) .... –