无法在 Ubuntu 中读取 .dat 或 .bin 文件“Segmentation fault (core dumped)" [英] Can't read .dat or .bin file in Ubuntu "Segmentation fault (core dumped)"

查看:71
本文介绍了无法在 Ubuntu 中读取 .dat 或 .bin 文件“Segmentation fault (core dumped)"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我最近才开始使用 Ubuntu.我正在构建这个非常简单的程序,它可以让我存储一些数据并在以后读取数据.

So, I just started using Ubuntu recently. I'm building this very simple program that will let me store some data and read back from it later on.

使用 C++、fstream,一些对象存储在 .dat 文件中.

Using C++, fstream, some objects are stored in .dat file.

// 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();
}

但是当我尝试(调用 query() 函数)从同一个文件中读取时,我收到分段错误(核心转储)"

But when I try to (call query() function) read from the same file, I'm getting "Segmentation fault (core dumped)"

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();
}

这曾经适用于Windows.这是为什么?

This used to work on windows. Why is that?

#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 字段.

Your Record contains std::string fields.

string 当然包含指针,并且可能包含一些带有虚函数的内部数据(因此有一个 vtable,这是一个隐藏的指针);那么该数据有指针.string 不是不是POD (但是一个固定的 char 数组将是,例如像 char name[48]; .... 这样的字段).

A string certainly contains pointers, and could contain some internal data with virtual functions (so having a vtable, which is a hidden pointer); then that data has pointers. And a string is not a POD (but a fixed array of char would be, e.g. a field like char name[48]; ....).

所以你的代码有未定义的行为所以你很幸运它在 Linux 上崩溃(并且不幸它似乎"可以在 Windows 上运行)......顺便说一句,当它是显然运行"(例如在您的 Windows 上)文件格式保持未定义"并且您将无法再次读取由旧版本程序(甚至相同版本)编写的数据文件由旧的或不同的编译器和 C++ 标准库编译的源代码).

So your code has undefined behavior so you are lucky that it crashes on Linux (and unlucky that it "appears" to work on Windows)... BTW, when it is apparently "running" (e.g. on your Windows) the file format stays "undefined" and you won't be able to read again a data file written by an older version of your program (or even the same source compiled by an older or different compiler and C++ standard library).

Linux 有 ASLR;这或许可以解释为什么您会遇到分段错误.顺便说一句,我想如果您在 same 进程(对您来说不是特别有用).

Linux has ASLR; that might explain why you've got a segmentation fault. BTW, I guess that Linux might not crash if you write and read the same data file in the same process (which is not particularly useful to you).

要了解更多信息,您必须深入了解实现细节,而您不想这样做.

To understand more, you'll have to dive into implementation details, and you don't want to.

显然,您需要实现一些序列化机制.然后首先(并详细地)指定您的文件格式(逐字节,endianness 和字大小"很重要,您的文件格式应该独立"于它们),也许使用一些 EBNF 符号.然后实现序列化例程,从基本的 POD 类型开始.或者使用一些序列化库.您的文件格式和代码应该是可移植的(例如,Raspberry Pi 和 Linux/PC 上的相同程序应该能够交换数据文件).

Apparently, you are required to implement some serialization machinery. Then specify first (and in details) your file format (byte by byte, endianness and "word size" matter and your file format should be "independent" of them), perhaps using some EBNF notation. Then implement the serialization routines, starting from elementary POD types. Or use some serialization library. Your file format and code should be portable (e.g. the same program on Raspberry Pi and on Linux/PC should be able to exchange data files).

顺便说一句,我更喜欢使用一些文本格式,也许使用 JSON, YAML(或 XML).或者也可以考虑像 SQLiteGDBM.在您的情况下,您的 Record 可以轻松映射到 SQLite 表中的行或 JSON 对象.也许你应该问问你的老师是否允许你使用它们......

BTW, I prefer much using some textual format, perhaps using JSON, YAML (or XML). Or consider also libraries like SQLite or GDBM. In your case, your Records map easily to rows in SQLite tables, or to JSON objects. Perhaps you should ask your teacher if you are allowed to use them....

这篇关于无法在 Ubuntu 中读取 .dat 或 .bin 文件“Segmentation fault (core dumped)"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆