C++ 从二进制文件读取元素时引发异常(引发异常:读取访问冲突。\u Pnext为0xB414D4。)
首先,我制作了一个简单的类:C++ 从二进制文件读取元素时引发异常(引发异常:读取访问冲突。\u Pnext为0xB414D4。),c++,fstream,unhandled-exception,C++,Fstream,Unhandled Exception,首先,我制作了一个简单的类: class test { public: test(string name="",int age=0); void getData(); void show(); private: string name; int age; }; test::test(string name,int age) { this->age = age; this->name = name; } void test::g
class test
{
public:
test(string name="",int age=0);
void getData();
void show();
private:
string name;
int age;
};
test::test(string name,int age)
{
this->age = age;
this->name = name;
}
void test::getData()
{
cin >> age;
cin >> name;
}
void test::show()
{
cout << "AGE:" << age<<"\n";
cout << "NAME:" << name << "\n";
}
类测试
{
公众:
测试(字符串名称=”,int age=0);
void getData();
void show();
私人:
字符串名;
智力年龄;
};
test::test(字符串名,int-age)
{
这个->年龄=年龄;
此->名称=名称;
}
void测试::getData()
{
cin>>年龄;
cin>>名称;
}
void测试::show()
{
cout这里的问题是,您试图读取test
对象,就好像它是一个简单的平面对象一样。出于许多原因,这几乎总是一个坏主意
在您的例子中,std::string成员根本不是一个简单的对象!实际上,std::string通常至少有一个指针成员指向它分配字符串的位置
如果您只需在一个会话中保存test
对象,并在另一个会话中恢复二进制表示,那么您就可以将这些指针设置为现在完全是垃圾的地址。这里的问题是,您试图读取test
对象,就像它是一个简单的平面对象一样。出于许多原因,这是alm这总是个坏主意
在您的例子中,std::string成员根本不是一个简单的对象!实际上,std::string通常至少有一个指针成员指向它分配字符串的位置
如果您只需在一个会话中保存stest
对象,并在另一个会话中恢复二进制表示,则可以将这些指针设置为现在完全是垃圾的地址
以稍后可恢复的方式保存数据结构的过程称为序列化,这是一个复杂的主题。os.read(reinterpret\u cast(&b),sizeof(b));
--这永远不会起作用,因为b
不是一种简单的可复制类型。这无法起作用的第二个原因是sizeof(b)
是一个常量,无论您在名称中有多少个字符。
您要做的是序列化测试
对象。如果我使用字符数组,它是否可以正常工作?如果字符串是固定长度数组,它将解决此问题,但您可能会让代码受到缓冲区溢出攻击。
int main()
{
ifstream os("new.dat", ios::binary);
test b;
os.read(reinterpret_cast<char*>(&b), sizeof(b));
b.show();
return 0;
}