1

私はこのstd::ofstream::writeメソッドのめちゃくちゃ奇妙な振る舞いを目撃しました。私は、ビットマップをファイルに保存することを含む、WindowsのBMPファイル形式の独自の処理を書いています-これは紹介です。std::ofstreamこれは、オブジェクトへの参照を指定して、ビットマップファイルのヘッダーを書き込むためのサブルーチンです。

void
BitmapFileManager::FileHeader::save(std::ofstream& fout) const
{
    word        w;  
    dword       dw; 
    char const* cw  = reinterpret_cast<char*>(w );
    char const* cdw = reinterpret_cast<char*>(dw);
    uint const  sw  = sizeof(w );
    uint const  sdw = sizeof(dw);

    fout.write(&sig1, sizeof(sig1));
    fout.write(&sig2, sizeof(sig2));
    dw = toLittleEndian(size);         fout.write(cdw, sdw);
    w  = toLittleEndian(reserved1);    fout.write(cw , sw );
    w  = toLittleEndian(reserved2);    fout.write(cw , sw );
    dw = toLittleEndian(pixelsOffset); fout.write(cdw, sdw);
}

ここでマークする唯一のことは、sig1sig2が両方ともタイプcharsizeof(word) = 2およびであるということsizeof(dword) = 4です。このコードにより、ファイルに1バイトが2回書き込まれ、次に4バイトのチャンク、2つの2バイトのチャンク、最後に4バイトのチャンクが書き込まれます。

結果の16進ダンプを見てください(以下にもいくつかありますが、無視してください)。

00000000  42 4d 42 4d 00 00 00 05  00 05 42 4d 00 00 28 00  |BMBM......BM..(.|

sig1sig2は2回出力され、適切な値は実際にはとBM、最初と何らかの奇妙な理由で11バイト目と12バイト目にも出力されます。この行の中で他の値を認識していません。しかし、すべての間にデバッグバイトを追加するとどうなるか見てくださいwrite

void
BitmapFileManager::FileHeader::save(std::ofstream& fout) const
{
    word        w;  
    dword       dw; 
    char const* cw  = reinterpret_cast<char*>(w );
    char const* cdw = reinterpret_cast<char*>(dw);
    uint const  sw  = sizeof(w );
    uint const  sdw = sizeof(dw);

    char nil = '*';
    fout.write(&sig1, sizeof(sig1));
    fout.write(&nil, sizeof(nil));
    fout.write(&sig2, sizeof(sig2));
    fout.write(&nil, sizeof(nil));
    dw = toLittleEndian(size);         fout.write(cdw, sdw);
    fout.write(&nil, sizeof(nil));
    w  = toLittleEndian(reserved1);    fout.write(cw , sw );
    fout.write(&nil, sizeof(nil));
    w  = toLittleEndian(reserved2);    fout.write(cw , sw );
    fout.write(&nil, sizeof(nil));
    dw = toLittleEndian(pixelsOffset); fout.write(cdw, sdw);
    fout.write(&nil, sizeof(nil));
}

16進ダンプは

00000000  42 2a 4d 2a 6c 3b 78 a0  2a 00 05 2a 00 05 2a 6c  |B*M*l;x?*..*..*l|
00000010  3b 78 a0 2a 28 00 00 00  28 00 00 00 28 00 00 00  |;x?*(...(...(...|

それは完全に大丈夫のようです。重複はなく、文字列をバイト*のシーケンスに分割します。1-1-4-2-2-4誰かが私がこれの理由を見つけるのを手伝ってもらえますか?コンパイル時のバグですか?Mac OS X Leopardで-O2を使用gcc version 4.0.1 (Apple Inc. build 5490)していますが、他のレベルでは何も変更されていません。

4

1 に答える 1

1

アダムローゼンフィールドはそれを釘付けにしました。あなたはaw(単語)の内容を取り、それをポインターとして扱っていました...そして、すべての地獄が解き放たれました。dwについても同じです。

その後のランダムなゴミ...

于 2011-11-20T00:04:36.033 に答える