c - 结构体在成员之后填充额外的字节

标签 c

#include <stdio.h>
#include <stdint.h>

typedef struct s{
    uint8_t a[1];
    uint16_t b;
    uint8_t c[1];
}s_t;

int main()
{
    printf("size = %d", sizeof(s_t));
    return 0;
}

我不确定为什么这个程序的输出是 6 个字节而不是 5 个。为什么编译器在最后一个成员之后填充一个额外的字节?看起来,如果您将最后一个成员数组的长度设置为 3,则填充的大小将变为 8。我无法解释这一点,因为这不仅仅适用于 2 个数组。

最佳答案

以下是编译器生成的对齐方式的说明:
字节:

+-----+---------------+  
|  0  | a[1]          |  
+-----+---------------+  
|  1  | N/A (padding) |  
+-----+---------------+  
|  2  | b             |  
+-----+---------------+  
|  3  | b             |  
+-----+---------------+  
|  4  |    c          |  
+-----+---------------+  

作为 16 位数量:

+---+------+----+  
| 0 | a[i] |    |  
+---+------+----+  
| 2 | b         |
+---+------+----+  
| 4 |   c  |    |
+---+------+----+  

处理器喜欢从偶数地址获取 16 位数量。
当它们位于奇数地址时,计算机可能必须进行 2 次 16 位读取,并从中提取未对齐的数据。

消除这种额外提取的简单方法是添加填充字节,以便 16 位数量对齐到偶数地址。

经验法则是先放置较大的项目,然后放置较小的项目。 应用此规则:

+---+------+  
| 0 | b    |  
+---+------+  
| 2 | a[1] |  
+---+------+  
| 3 | c    |  
+---+------+  

该规则消除了对额外填充字节的需要。

关于c - 结构体在成员之后填充额外的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51995304/

相关文章:

Pthread 中的并发

将位域转换为 int

c - 为什么使用文本编辑器创建的文件比预期多了一个字节?

python - 如何使用 SWIG 访问嵌套的 union 成员?

c - 为什么有些算术运算比平时花费更多的时间?

c - 由于循环限制,排序给出不一致的结果

c - gdb:是否可以根据调试符号中不存在的用户定义结构来转换/重新解释序列

c - OpenGL(在 Ubuntu 中): glGetError() returns GL_INVALID_OPERATION

CUDA - 多个内核来计算单个值

c - C 中只读变量的 Getter