c++ - 将用户定义的数据类型保存到 C++ 文件中

标签 c++ fwrite fread

我有这样一个类:

struct SomeClass{

    SomeClass(){}

    SomeClass(const SomeClass& rhs):
    _m1(rhs._m1),
    _m2(rhs._m2),
    _m3(rhs._m3),
    _m4(rhs._m4){}

    SomeClass& operator=(const SomeClass& rhs){
    // same as above
    return *this;
    }

    int _m1;
    std::vector<int> _m2;
    std::vector<int> _m3;
    int _m4;
};

在我的程序中的某个时刻,我想将存储在 SomeClass 对象中的数据保存起来供以后使用:

    SomeClass someObj = arr->getBest(); // arr is a pointer to AnotherClass,
                                        // in which different SomeClass
                                        // objects are initialized and then
                                        // involved in various 
                                        // computations in AnotherClass, 
                                        // finally the best one SomeClass 
                                        // object will be save here
    fwrite(&someObj, sizeof(SomeClass), 1, saveFile);

将文件保存到saveFile后,我尝试读取它并得到一个错误:

    SomeClass readingSomeObj;
    fread(&readingSomeObj, sizeof(SomeClass), 1, savedFile));

编译器提示“访问冲突读取位置 0x...”。通过观察 VS 中的本地人,我看到 readingSomeObj 的另外两个字段,即 _m1_m4 有值,但没有 _m2_m3,在 VS 中显示“无法读取内存”。 vs error prompt

它进一步将问题与 SomeClass 联系起来,特别是这一行 _m2(rhs._m2),

但是当我在 fwrite(&someObj, sizeof(SomeClass), 1, saveFile); 行中保存 someObj 时,我确实看到了两个成员 someObj 的 _m2_m3 有值(将鼠标悬停在 &someObj 上)。

我不知道出了什么问题。我的猜测是 SomeClass 的构造函数有问题,但作为 C++ 的新手,我不知道如何更正它。在程序的其他部分,我使用了SomeClass 的空构造函数来初始化AnotherClass 的成员。但是除了这个保存/阅读部分之外,一切都运行良好。我正在寻找您的慷慨帮助,非常感谢!

最佳答案

您对不成立的数据类型做出了大量假设。最令人震惊的是,它的所有字节都存储在内存中的“行”中,并且彼此相邻,这是 block 式复制和读取唯一可行的方法。

这可能适用于 POD(模对齐和字节序考虑因素),但它不适用于复杂的数据类型,如 vector,它指向实际存储在别处的“真实”数据(通过动态分配)。

您的反序列化 vector 几乎完全由长期以来无效的指针值组成。

您的序列化例程必须比这更智能。最终没有“唯一”的方法来做到这一点。您可以定义自己的格式,也可以使用一些现成的序列化解决方案,这些解决方案已经具有支持标准容器的格式。

您可以通过 Google“C++ 类序列化”获得一些想法。

关于c++ - 将用户定义的数据类型保存到 C++ 文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53451005/

相关文章:

c++ - 为什么一旦我将引用声明为 const,它就可以接受不同类型的数据?

c - fwrite 段错误 - 大小为 4 的无效读取

PHP 拆分 fwrite 以节省内存

c - 为什么第二次使用 fread() 时它不是从头开始而是从第一次 fread() 读取的末尾开始读取文件?

c++ - gcc 接受并拒绝带有嵌套泛型 lambda 的此代码,为什么?

c++ - Qt moveToThread,带参数的信号/槽

c++ - std::vector 调整大小与 fread 期间的保留

C++ - 将 Hunspell 与 MFC 结合使用

C - 将文本中的分类数据放入结构中