下面的代码有什么问题。对于某些输入和某些特殊输入的崩溃,它运行完全正常吗?
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
struct event {
string date,time,content;
bool is_high_priority;
};
int main() {
event one,two;
one.is_high_priority=false;
char tmp;
ofstream out_file("events" , ios::binary );
cout<<"\nEnter Date(dd.mm) ";
cin>>one.date;
cout<<"\nEnter Time(hh:mm:ss) ";
cin>>one.time;
cout<<"\nenter content";
cin>>one.content;
if(tmp == 't')
one.is_high_priority = true;
else
one.is_high_priority = false;
out_file.write((char*) &one, sizeof(one) );
out_file.close();
ifstream in_file("events" , ios::binary );
in_file.read((char*)&two,sizeof(two));
cout<<two.date<<" "<<two.time<<" "<<two.content<<" "<<two.is_high_priority;
in_file.close();
}
这些输入崩溃了: 输入日期(dd.mm)ankmjjdn md
输入时间(hh:mm:ss) 输入contentsnjs sjnsn
答案 0 :(得分:6)
您不能只将std::string
对象的字节保存到文件中,然后再次加载它们。 std::string
包含指向动态分配内存的指针,保存/加载只会复制指针本身,而不是指向数据。
答案 1 :(得分:1)
if(tmp == 't')
tmp
是一个本地未初始化的变量,您正在使用它,如上所示。
因此,您的代码会调用未定义的行为。没有什么可以说的了。
答案 2 :(得分:0)
正如@sth指出的那样,将指针复制到文件并重新解释它们最终会成为无重复的场景。
然而,我认为有一些更微妙的东西,如果我错了,请纠正我。 程序并不总是在所有输入上崩溃。它甚至不依赖于弦的长度。我尝试用一些测试用例来运行程序。
请注意,角色'space`被视为分隔符。即使您提供输入,空格后的字符也会被下一个字符串占用。
因此,第三个字符串占用的值直到'space'剩余的输入(直到回车)仍然在输入缓冲区上。
我怀疑当第二个对象是从istream构造时,'space'之后的字符串会覆盖一个指针,这会导致损坏检测。