c - 结构的大小怎么可能是 4 的非倍数?

标签 c struct sizeof

我是结构的新手,正在学习如何找到结构的大小。我知道填充是如何发挥作用以正确对齐内存的。据我所知,对齐是为了使内存中的大小成为 4 的倍数。 我在 GCC 上尝试了以下代码。

struct books{
  short int number;
  char name[3];
}book;
printf("%lu",sizeof(book));

本来我以为short int会占2个字节,后面是从内存的第三个位置开始的字符数组。然后,字符数组将需要 3 个字节的填充,这将使大小为 8。像这样,其中每个单词代表内存中的一个字节。

短短字符字符

字符填充填充填充

但是在运行时它的大小为 6,这让我很困惑。

任何帮助将不胜感激,谢谢!

最佳答案

通常,插入padding 是为了允许对齐访问结构的内部元素,而不是为了让整个结构是多个单词的大小。对齐是一个编译器实现问题,不是 C 标准的要求。

因此,长度为 3 个字节的 char 元素不需要对齐,因为它们是字节元素。

虽然不是必需的,但首选短元素需要在短边界上对齐——这意味着偶数地址。通过在短边界上对齐,编译器可以发出单个加载短指令,而不必加载一个字、掩码,然后移位。

在这种情况下,填充可能但不一定发生在末尾而不是中间。您将必须编写代码来转储元素的地址以确定填充发生的位置。

编辑:。正如@Euguen Sh 所提到的,即使您发现编译器用于结构的填充方案,编译器也可以在不同版本的编译器中修改它。

依靠编译器的填充方案是不明智的。总有一些方法可以以您不会猜测对齐方式的方式访问元素。

sizeof() 运算符用于让您查看使用了多少内存,并了解如果该指针递增 1 (ptr++),将向结构的 ptr 添加多少内存。

编辑 2,打包:可以使用 __packed__ 属性打包结构以防止填充。在设计结构时,明智的做法是使用自然堆积的元素。这在通过通信链路发送数据时尤为重要。精心设计的结构避免了在结构中间填充的需要。设计不佳的结构随后使用 __packed__ 属性进行编译,可能包含未自然对齐的内部元素。人们可能会这样做以确保该结构将按照最初设计的方式通过电线传输。随着用于通过线路传输数据的 JSON 的引入,这种类型的努力已经减少。

关于c - 结构的大小怎么可能是 4 的非倍数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55594696/

相关文章:

objective-c - 计算垂直于另一条线的中点的线

c - 为什么 "strupr"的这个实现不起作用?

c++ - 初始化一个包含 vector 的结构

c - 使用 sizeof 访问结构成员

html - C 语言的服务器实现

c - 在 Ansi C 中 - 'decay' 在哪里定义,它发生的所有情况都在哪里记录?

Swift 结构扩展 : 'Cannot convert return expression of type <type> to return type <type>'

C qsort 嵌套结构数组

c++ - 使用 memset 将派生结构归零

c++ - 作为参数传递的数组的 sizeof 的奇怪行为