std :: ofstream无缘无故地重复和丢失书面数据

时间:2011-11-19 22:40:08

标签: c++ file ofstream

我刚刚目睹了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) = 2sizeof(dword) = 4。这段代码应该导致两次向文件写入一个字节,然后是四字节块,两个两字节块,最后是一个四字节块。

看看结果的十六进制转储(后面还有一些事情,但忽略它们):

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

sig1sig2打印两次,其值正确为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));
}

十六进制转储变为

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上使用gcc version 4.0.1 (Apple Inc. build 5490)和-O2,但其他级别没有任何改变。

1 个答案:

答案 0 :(得分:1)

亚当罗森菲尔德钉了它。你正在拿w(一个单词)的内容并把它作为一个指针......然后一切都崩溃了。 dw也是一样。

之后的随机垃圾......