将用户定义的数据类型保存到 C++ 文件中
Save user defined data type to a file in C++
我有一个 class 这样的:
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));
编译器投诉"Access violation reading location 0x..."。通过观察 VS 中的本地人,我看到 readingSomeObj
的其他两个字段,即 _m1
和 _m4
有值,但没有 _m2
和 _m3
,在 VS 中显示 "unable to read memory"。
它进一步将问题与 SomeClass
联系起来,特别是这一行 _m2(rhs._m2),
。
但是当我在 fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
行中保存 someObj
时,我确实看到 someObj
的两个成员 _m2
和 _m3
有值(将鼠标悬停在 &someObj
).
我不知道出了什么问题。我的猜测是 SomeClass
的构造函数有问题,但作为 C++ 的新手,我不知道如何更正它。在我程序的其他部分,我使用 SomeClass
的空构造函数来初始化 AnotherClass
的一个成员。但是除了这个 saving/reading 部分之外,一切都运行良好。我正在寻找您的慷慨帮助,并感谢一百万!
你不能像这样序列化向量。他们分配了内存,所以做类似的事情:
- 将整数存储到文件
- 存储第一个向量的大小
- 存储第一个向量的内容
- 对第二个向量做同样的事情
那么当你阅读你的文件时:
- 读取你的两个整数
- 读取你的第一个向量大小,分配向量
- 读取第一个向量的值
- 对第二个向量执行相同的操作。
您也可以使用像 Boost.Serialization 这样的序列化库,它以更可靠的方式处理这部分内容。
您对不成立的数据类型做出了大量假设。最令人震惊的是,它的所有字节都存储在内存中的 "row" 中,并且彼此相邻,这是块式复制和读取唯一可行的方法。
这可能适用于 PODs(模数对齐和字节顺序考虑),但它不适用于像 vector
这样的复杂数据类型,它指向实际存储在其他地方的 "real" 数据(通过动态分配)。
您的反序列化向量几乎完全由长期以来无效的指针值组成。
您的序列化例程必须比这更智能。最终没有 "one" 方法可以做到这一点。您可以定义自己的格式,也可以使用一些现成的序列化解决方案,这些解决方案已经具有支持标准容器的格式。
您可以 Google "C++ class serialisation" 获得一些想法。
我有一个 class 这样的:
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));
编译器投诉"Access violation reading location 0x..."。通过观察 VS 中的本地人,我看到 readingSomeObj
的其他两个字段,即 _m1
和 _m4
有值,但没有 _m2
和 _m3
,在 VS 中显示 "unable to read memory"。
它进一步将问题与 SomeClass
联系起来,特别是这一行 _m2(rhs._m2),
。
但是当我在 fwrite(&someObj, sizeof(SomeClass), 1, saveFile);
行中保存 someObj
时,我确实看到 someObj
的两个成员 _m2
和 _m3
有值(将鼠标悬停在 &someObj
).
我不知道出了什么问题。我的猜测是 SomeClass
的构造函数有问题,但作为 C++ 的新手,我不知道如何更正它。在我程序的其他部分,我使用 SomeClass
的空构造函数来初始化 AnotherClass
的一个成员。但是除了这个 saving/reading 部分之外,一切都运行良好。我正在寻找您的慷慨帮助,并感谢一百万!
你不能像这样序列化向量。他们分配了内存,所以做类似的事情:
- 将整数存储到文件
- 存储第一个向量的大小
- 存储第一个向量的内容
- 对第二个向量做同样的事情
那么当你阅读你的文件时:
- 读取你的两个整数
- 读取你的第一个向量大小,分配向量
- 读取第一个向量的值
- 对第二个向量执行相同的操作。
您也可以使用像 Boost.Serialization 这样的序列化库,它以更可靠的方式处理这部分内容。
您对不成立的数据类型做出了大量假设。最令人震惊的是,它的所有字节都存储在内存中的 "row" 中,并且彼此相邻,这是块式复制和读取唯一可行的方法。
这可能适用于 PODs(模数对齐和字节顺序考虑),但它不适用于像 vector
这样的复杂数据类型,它指向实际存储在其他地方的 "real" 数据(通过动态分配)。
您的反序列化向量几乎完全由长期以来无效的指针值组成。
您的序列化例程必须比这更智能。最终没有 "one" 方法可以做到这一点。您可以定义自己的格式,也可以使用一些现成的序列化解决方案,这些解决方案已经具有支持标准容器的格式。
您可以 Google "C++ class serialisation" 获得一些想法。