【问题标题】:why the size of FILE structure instance is 216 bytes in 64 bit os and 148 Bytes in 32 bit os?为什么 FILE 结构实例的大小在 64 位操作系统中为 216 字节,在 32 位操作系统中为 148 字节?
【发布时间】:2019-04-27 19:19:23
【问题描述】:

如果我打印 FILEFILE 实例的大小,则结果为 216 字节 64 位系统和 32 位系统中的 148 字节(操作系统:Ubuntu 16.04,编译:GCC)

 printf("size : %zu",sizeof(FILE)); 

FILE *fp;
printf("size : %zu",sizeof(*fp));

谁能解释为什么它显示这么大,因为我检查了结构成员主要是指针。

【问题讨论】:

  • 尽管FILE 的实现内部格式(您不必关心)为什么要使用%d 打印size_t 表达式?那应该是%zu。如果成员“主要是指针”,请考虑 32 位和 64 位表示中的每个指针从前者到后者的大小实际上将 加倍
  • 它确实发挥了重要作用。使用错误的格式说明符基本上是欺骗 printf,并且如果/当参数不是相应说明符所期望的精确类型时调用未定义的行为。编码世界中有足够的UB;没有理由用琐碎的事情来添加它,尤其是当它们足够简单以首先做正确的事情时。例如:如果 size_tint 在您的架构上分别是 64 位和 32 位(大多数 64 位拱门都是这样),那么您会将 64 位值推送到需要 32 位值的函数。
  • 我检查了 %zu 并更新了相同的内容,谢谢。
  • 顺便说一句,实际上,FILE 占用更多资源:一些缓冲区(千字节)和 file descriptor(操作系统内核已知的资源)
  • 您期望哪些值以及为什么?

标签: c file data-structures file-handling


【解决方案1】:

结果在 64 位系统中为 216 字节,在 32 位系统中为 148 字节

谁能解释为什么它显示这么大,因为我检查了结构成员主要是指针。

FILE 结构的内容是特定于实现的(这意味着它们在不同的平台上是不同的)。

在 32 位系统上,指针的大小通常为 4 字节,而在 64 位系统上,指针的大小通常为 8 字节。

因此,您看到的大小差异 (216 - 148 = 68) 可以很容易地计算出来。 (据我记得这个结构在 Ubuntu GCC 中有大约 15 个指针)。 除了指针之外,intlong(可以是FILE 结构的一部分)等其他类型的大小可能与 32 位和 64 位系统不同。

包括以下@MatteoItalia cmets:

特别是,使用 glibc 中的 this definition(和 _IO_USE_OLD_IO_FILE 未定义)我确实得到了 148 个字节(带有 4 字节 int、指针、size_t__off_t)。

至于差异,有超过 17 个指针(加上填充!)可以解释差异,但最后还有一些显式填充使计算复杂化(它在 64 位上确实变得更小,如 @ 987654330@ 在 32 位上是 40,但在 64 位上是 24)

【讨论】:

  • 谢谢,关于 32 位和 64 位系统的区别我明白了。现在你能解释一下为什么 32 位操作系统的大小是 148。
  • @new_learner 因为那里有 148 字节的数据?它实际上是特定于实现的,具体取决于您的系统标头;从你的编译器包含目录中挖掘它们,总结字段大小(考虑填充),你会看到它加起来是 148。
  • 特别是,使用 glibc 中的 this definition(和 _IO_USE_OLD_IO_FILE 未定义)我确实得到了 148 个字节(使用 4 字节 int、指针、size_t__off_t)。
  • 至于差异,有超过 17 个指针(加上填充!)可以解释差异,但最后还有一些显式填充使计算复杂化(它确实变小了64 位,因为15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t) 在 32 位上是 40,但在 64 位上是 24)。
  • @MatteoItalia:我可以在答案中包含您的 cmets 吗?
【解决方案2】:

FILE 结构的内容和大小完全特定于实现。它在 64 位模式下恰好是 216 字节,在 32 位模式下是 148 字节。差异可能来自 32 位和 64 位模式之间此结构的某些成员的不同大小:指针更大,以及size_t 和文件位置,这实际上取决于 C 库如何处理标准流。

请注意,一些额外的信息可能存储在结构之外...在任何情况下,您都无法将FILE 保存到局部变量并安全地恢复它。

注意FILE 也可能是一个不完整的类型:typedef 指向一个没有定义的结构的指针,在这种情况下sizeof(FILE) 会导致编译错误。将定义放在<stdio.h> 标头中的主要原因是允许宏直接访问成员。查看您的 <stdio.h> 文件并查找其他开源实现,例如 newlib 或 glibc。

此外,C 标准不要求 FILE 是结构的 typedef:它可能不是结构,它可以定义为 int

【讨论】:

  • @注意 FILE 可能根本不是一个结构。它可以定义为 int 。 FILE 是一个类型定义的结构:typedef struct _IO_FILE FILE; (在 stdio.h 中定义类型并在 libio.h 中声明)
  • @new_learner FILE 是一个类型定义的结构:typedef struct _IO_FILE FILE; (在 stdio.h 中定义类型并在 libio.h 中声明) 这仅适用于您查看的一个实现。还有其他 - 许多其他。
猜你喜欢
  • 1970-01-01
  • 2013-08-29
  • 2012-12-02
  • 2011-02-20
  • 2013-10-31
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多