【发布时间】:2020-11-17 09:05:42
【问题描述】:
我目前正在尝试使用以下代码读取位图文件头:
#include <fstream>
using namespace std;
struct BitMapFileHeader {
uint16_t bfType;
uint32_t bfSize;
uint16_t bfReserved1;
uint16_t bfReserved2;
uint32_t bfOffBits;
} file_header;
int main() {
ifstream fin;
fin.open("input.bmp", ios::binary);
fin.read(reinterpret_cast<char*>(&file_header), sizeof(file_header));
}
我文件的前几个字节是42 4D 36 53 07 00 00 00。 file_header.bfType 显示 19778 的正确值包含在第 1 和第 2 个字节中,但是 filder_header.bfSize 显示 7,它存储在第 5 个字节中,并且似乎跳过了第 3 和第 4 个字节。
看来我遇到了this问题的第二个答案的评论中提到的问题。尽管发现了问题,但我不知道如何解决它。有人能指出我正确的方向吗?
编辑:由于内存访问未对齐的性能问题,有些人不建议打包结构成员。除了一个一个地填充每个结构成员之外,还有什么办法可以避免这种性能损失?
【问题讨论】:
-
您很可能需要将结构的打包更改为字节对齐。这是使用
#pragma、编译器扩展或某些编译器选项完成的,具体取决于编译器。 -
您应该提及您正在使用的编译器。
-
@PaulMcKenzie 这是一个将提交给在线评审系统的问题的一部分,编译器和C++标准似乎是随机变化的,所以我无法给出明确的答案。
-
这不是 C++ 标准问题——它只是一个编译器问题。它取决于如何设置结构对齐方式。 See this。对于 g++,它是使用
__attribute__((packed))完成的,对于 Visual C++,它是#pragma pack(1)等,以及push和pop集合#pragmas 等。至于你的编辑,这没有任何意义与性能有关。您正在尝试将位图标头“覆盖”到结构上而没有任何失败。 -
@PaulMcKenzie 谢谢。
#pragma pack(1)工作,所以我假设编译器是 Visual C++
标签: c++ struct binaryfiles memory-alignment