1

従業員のデータベースを保存し、外部ファイルに保存するプログラムを作成しようとしています。.dat ファイルからベクトルを読み取ってプログラムにロードする関数はファイルを読み取りますが、ロードされたベクトルを表示または変更しようとすると、プログラムがクラッシュします。

//displays vector
void Database:: displayAll() const
{
    for(std::vector<Employee>::const_iterator iter = mEmployees.begin(); iter != mEmployees.end(); ++iter)
    {
        iter -> display();
    }

}

std::vector<Employee> mEmployees;

void Database::readData()
{
    ifstream empIn("employee.dat" , ios::binary);
    empIn.seekg(0,ifstream::end);
    long size2 = empIn.tellg();
    empIn.seekg(0,ifstream::beg);
    mEmployees.resize(size2);
    empIn.read((char*)&mEmployees, size2);
    empIn.close();
    cout << mEmployees.size() << endl; //this tests whether or not it reads.
}
4

2 に答える 2

3

あなたは の宣言を私たちに見せていませんが、私はそれがある種の であるmEmployeesと推測しています。問題は、ファイルをコンテンツではなく、オブジェクトstd::vectorに読み込もうとしていることです。これにより、 およびその隣の他のメモリvectorが破損し、さらにクラッシュが発生します。vector

代わりにおそらく必要なのは次のとおりです。

empIn.read((char*)&mEmployees[0], size2);

またはC++11の場合:

empIn.read((char*)mEmployees.data(), size2);

実際にファイルの内容vector.

なぜこれが起こっているのかを理解するには、 aの内容がそれ自体vectorに保存されていないことを知っておく必要があります(サイズは動的です)。代わりに、 の一般的な実装では、コンテンツが実際に保持されるフリー ストアのどこかに、ストレージ領域の開始点と終了点へのポインターがあります。ファイルを のメモリ レイアウトに読み込もうとすると、それらのポインタとそれ自体を超えるメモリが上書きされ、とりわけベクトルが破損します。vectorvectorvectorvector

于 2012-12-26T03:16:16.413 に答える
0

to へのキャスト(char*)は、コンパイラが通常行う型チェックを破棄するように指示します。ifstreamを渡す必要があるため、この場合はキャストを実行する必要がありますchar*。問題は、これはかなり率直な手段であり、 から変換しようとしているときにreinterpret_castから変換していることを警告できないことです。vector<Employee>*Employee*

このようなキャストは低レベルの操作であることを覚えておいてください。その目的は、「間違っているように見えても、自分が何をしているのかを知っている」ことをコンパイラーに伝えることです。細心の注意を払って使用する必要があります。

あなたがやっていることのより良い、そして修正された形式は次のようになります:

empIn.read( reinterpret_cast<char*>(&mEmployees[0]), mEmployees.size() );
于 2012-12-26T03:34:47.343 に答える