将带有指针数组的结构保存到文件中
Save struct with an array of pointers into a file
我正在开发c++,我需要将这个结构保存到一个文件中:
struct myStruct{
int value;
int value2;
MyClass * myClass[10];
};
我保存这个结构的方式如下:
myStruct my_struct;
my_struct.value = 1;
my_struct.value2 = 2;
for ( int i = 0; i < 10; i++){
my_struct.myClass[i] = new MyClass();
}
FILE* f = fopen(path.c_str(), "wb");
if ( f != NULL){
fwrite(&my_struct, sizeof(myStruct), 1, f);
fclose(f);
}
但是,当我想读取这个文件时,我的程序在尝试访问"MyClass"数组时崩溃:
FILE* f = fopen(path.c_str(), "rb");
if ( f != NULL){
fread(&my_struct2, sizeof(struct myStruct), 1, f);
fclose(f);
}
for ( int i = 0; i < 10; i ++ ){
if ( my_struct2.myClass[i] != NULL ){
//Here is the crash
}
}
我一直在找,但找不到解决方案。我只找到关于结构数组的主题。我知道也许我找得不太好。
谢谢。
您的MyStruct
包含20个指向其他结构的指针。
通过fwrite
()将MyStruct
的内容写入一个文件,您已经成功地将其他结构的20个原始内存地址以及MyStruct
类的其他成员写入该文件。
当然,当你试图在另一个过程中读回它们时,这是完全没有意义的。您已经读回了20个原始内存地址。这对一个完全无关的过程毫无意义。而且,毫不奇怪,访问这些内存地址会导致崩溃,因为这些内存地址完全是随机值。
您的代码需要做的不是向文件写入20个原始指针地址,而是这些指针的内容以及它们指向的内容
我想在Sam的回答中添加一些内容,即使我知道这不是代码评审,但您正在用C++编写C。
C++不应该用C来编码,它不想……它一生都在努力打破与被抛弃的父亲的束缚,超越他,探索解决问题和构建高效代码的新含义和方法。不要这样对他。。。(顺便说一句,我喜欢C,不推荐显然是个笑话;)
以下是我的做法:
#include <fstream>
#include <iostream>
class MyClass
{
public:
MyClass() : _type(-1) {}
MyClass(int type) : _type(type) {}
inline const int &type() const
{ return _type; }
private:
int _type;
};
// -- overload of operator<< that permits me to write a MyClass* to a stream
std::ostream &operator<<(std::ostream &stream, MyClass *myClass)
{
stream << "myClass::type: " << myClass->type();
return stream;
}
struct MyStruct
{
int value;
int value2;
MyClass *myClasses[10];
MyStruct()
{
value = -1;
value2 = 1;
for (std::size_t i = 0 ; i < 10 ; ++i)
{ myClasses[i] = new MyClass(-i); }
}
};
// -- overload of operator<< that permits me to write a MyStruct to a stream
std::ostream &operator<<(std::ostream &stream, const MyStruct &myStruct)
{
stream << "myStruct::"
<< "nt value: " << myStruct.value
<< "nt value2: " << myStruct.value2
<< "nt myClasses: ";
for (std::size_t i = 0 ; i < 10 ; ++i)
{ stream << "ntt " << myStruct.myClasses[i]; }
return stream;
}
int main()
{
std::ofstream outputFile("output.txt");
if (outputFile.is_open() == false)
{ std::cerr << "Could not open file." << std::endl; return -1; }
outputFile << MyStruct() << std::endl; // -- this is where the information is written into the file
outputFile.close();
}
看看写结构的简单方法,你甚至可以用运算符>>重载的方法把它放回结构中,额外的好处是你可以在任何ostream上使用,这意味着它可以与sstream、std::cout和所有东西一起使用!
尽管如此,这并不是真正的c++风格,因为有太多(未受保护的)指针和未经检查的神奇数字大小(MyClass *myClasses[10];
,这对我来说是不允许的,因为它暗示了这件事:for (std::size_t i = 0 ; i < 10 ; ++i)
,而这件事让我不寒而栗)。
我可能会在这里使用std::数组,但我想保留您定义的MyStruct,这样示例就可以"接近"您所写的内容。另一种方法是使用std::unique_ptr或std::shared_ptr。
这可能看起来有点吃力或令人生畏,但你可能会发现这在未来很有用。使用std容器(数组、集合、向量、映射等)、unique_ptr和shared_ptr也是如此。但我向你保证,花一些时间来理解它们并学习如何使用它们是值得的。它使事情变得更简单、更安全。
早些时候让我发抖的是这样写的:
std::array<MyClass, 10> myClasses;
循环如下:
for (std::size_t i = 0 ; i < myClasses.size() ; ++i)
{ myClasses[i].type(); }
for (std::array<MyClass, 10>::iterator itC = myClasses.begin() ; itC != myClasses.end() ; ++itC)
{ itC->type(); }
或者更好的是,一种c++11编写循环的方法,我发现它更容易读写:
for (auto myClass : myClasses)
{ myClass.type(); }
注意,如果你想在这个里面修改myClass,你需要写auto& myClass : myClasses
希望它能帮助你。
如果结构体my_struct
包含纯静态数据(即在编译时为其分配内存的数据),则使用fwrite(&my_struct, sizeof(myStruct), 1, f);
是很好的。如果它包含动态数据(即在运行时为其分配内存的数据),则需要手动存储此类动态数据。重载operator<<
(如my@vianney所示)是保存/序列化动态数据的好方法。
- 将结构向量保存到文件中,并从C++文件中读取结构向量
- Windows 将标准的 C 文件结构注入到正在运行的进程中
- 多线程和共享资源:使用C++定期将数据从缓冲区(数据结构)复制到文件
- 将由结构构建的数组传递到将数据存储到文件中的函数
- 如何读写结构向量到文件
- 通过将结构信息从二进制文件读取到数组中,然后返回到文件C
- 将结构从二进制文件读取到链表,导致无限循环
- 将带有指针数组的结构保存到文件中
- C 将字符串从结构保存到文本文件中
- 将包含数组数据成员的结构保存到文件
- 将matlab中的libsvm模型结构保存到可以用C++读取的.model文件中
- 将树数据结构转储到文件/从文件还原树数据结构
- 使用函数将结构写入/读取到文件,Visual C++ 2008 express
- 将结构的 c++ 数组保存到文件和问题中以向其添加新元素
- 将结构信息从文件读取到空数组中
- 将复杂结构存储到文件中
- C/ c++:读写时间戳数据到文件,支持多体系结构
- 保存一个结构向量到一个Tab分隔的文本文件
- 如何在c++中写一个结构体到文件并读取文件
- 如何将结构导出到文件,然后对文件进行内存映射