1

以下のコードの何が問題なのですか? 一部の入力では問題なく動作し、一部の特別な入力ではクラッシュしますか?

#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();

}

これらの入力でクラッシュしました: Enter Date(dd.mm) ankmjjdn md

時刻 (hh:mm:ss) を入力してください contentnjs sjnsn を入力してください

4

3 に答える 3

6

std::stringオブジェクトのバイトをファイルに保存して、後で再度ロードすることはできません。には動的に割り当てられたメモリへのstd::stringポインタが含まれており、保存/読み込みでは、データを指すのではなく、ポインタ自体が複製されます。

于 2012-08-11T12:24:19.533 に答える
1
if(tmp == 't') 

tmpはローカルの初期化されていない変数であり、上記のように使用しています。

したがって、コードは未定義の動作を呼び出します。これ以上言うことはできません。

于 2012-08-11T12:23:11.740 に答える
0

@sthが指摘しているように、ポインタをファイルにコピーして再解釈すると、重複のないシナリオになります。

しかし、もっと微妙なことがあると思います。間違っている場合は訂正してください。プログラムは、すべての入力で常にクラッシュするとは限りません。弦の長さにも依存しません。いくつかのテストケースでプログラムを実行してみました。

文字「スペース」は区切り文字として扱われていることに注意してください。入力しても、スペースの後の文字は次の文字列に使用されます。

したがって、3番目の文字列は「スペース」まで値を取ります。残りの入力(キャリッジリターンまで)はまだ入力バッファにあります。

2番目のオブジェクトがistreamから構築されている場合、「スペース」の後の文字列がポインタを上書きし、これが破損の検出を引き起こしているのではないかと疑っています。

于 2012-08-11T16:04:00.150 に答える