为什么fwrite为uint8_t写两个字节?

时间:2018-04-18 09:31:50

标签: c binary posix

C不太熟练。这可能只是一个新手问题。

我正在尝试将3个字节写入文件,但最终以4结尾。

#include <stdio.h>
#include <stdlib.h>

struct a {
  uint8_t x;
  uint16_t y;
};

int main()
{
  struct a record = { 1, 2 };
  FILE *fp = fopen("example.bin", "w");
  fwrite(&record, sizeof(struct a), 1, fp);
  fclose(fp);
}

出于某种原因,我最终得到:

$ hexdump -C example.bin
00000000  01 00 02 00                                       |....|
00000004

我期待:01 02 00

以下是我的c编译器的版本,以防这是与硬件/编译器相关的。

$ cc --version
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.5.0
Thread model: posix

2 个答案:

答案 0 :(得分:5)

  

我正在尝试将3个字节写入文件,但最终得到4个。

您可能瞄准写入3个字节但实际上正在编写 $cMode=''; if($mode == "None"){ $cMode = 'LIKE "%"'; }else{ $arr = explode('-',$mode); $cMode ="BETWEEN $arr[0] AND $arr[1]"; } $query = "SELECT * FROM sections WHERE code $cMode"; ,这可能是4,因为编译器插入了一个填充字节用于对齐。也许你假设一个结构的大小等于其成员的大小总和,并且没有考虑到可能的填充。

通常,编译器可以自由地插入填充以便进行对齐(除非在结构的第一个成员之前不能填充)。

如果你写下个人成员,你就会看到预期的输出:

sizeof(struct a)

P.S。:确保错误检查所有可能失败的功能(fopen,fwrite等)。

答案 1 :(得分:0)

结构通常由编译器填充 - 在x之后插入空白空间,以便y与16位边界对齐。

GCC提供__attribute__((packed))来禁用此行为;见these docs