c - 使用不同类型的字段填充结构

标签 c padding

我已经提到了this question ,但仍然找不到以下案例的答案。 为什么填充不适用于 test1 的情况?

#include <stdio.h>

typedef unsigned short u16;
typedef unsigned char u8;
typedef struct
{
    u8 a[5];
    u8 b;
    u8 c;
} test1;

typedef struct
{
    u8 a[5];
    u16 b;
} test2;

int main(void) {
    test1 t1;
    test2 t2;
    printf("t1 = %d\n", sizeof(t1));
    printf("t2 = %d\n", sizeof(t2));
    return 0;
}

Output:
t1 = 7
t2 = 8

更新

在 @ryyker 和 @Ajay Brahmakshatriya 的回答之后,我制作了另一个测试代码,似乎答案不适用于这种情况......如果填充大小为 3,因为 test1 类型的大小是3,为什么test2的大小不是9而是7?

#include <stdio.h>

typedef unsigned short u16;
typedef unsigned char u8;
typedef struct
{
    u8 a;
    u8 b;
    u8 c;
} test1;

typedef struct
{
    test1 a[2];
    u8 b;
} test2;

int main(void) {
    test1 t1;
    test2 t2;
    printf("t1 = %d\n", sizeof(t1));
    printf("t2 = %d\n", sizeof(t2));
    return 0;
}

Output:
t1 = 3
t2 = 7

最佳答案

结构体的对齐要求大于等于其每个成员的对齐要求。此外,数组的对齐要求与其元素的对齐要求相同。

如果u8的对齐要求为1字节,u16的对齐要求为2字节,则test1的对齐要求为至少 1 个字节,而 test2 则至少 2 个字节。

由于test2的对齐要求是2个字节,所以它的大小也应该是2个字节的倍数(这样如果你声明一个结构体数组,那么数组中的所有元素都可以是正确对齐)。

test2 元素的大小总和为 7 个字节。最接近 2 的倍数是 8 个字节。 对于test1,由于对齐要求仅为1字节,因此7是可接受的大小。

最后,只要满足上述所有约束,实现就可以向结构添加任意数量的填充。所以没有正确的方法来回答“为什么这个结构体的大小不等于我计算的大小?”这个问题。我这里所掌握的可能是您的实现选择当前大小的原因。

关于c - 使用不同类型的字段填充结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60056847/

相关文章:

c# - 在 Xamarin C# 中向 MKMapView 的边缘添加填充

c - 结构在内存中的布局定义得如何?

c - 为什么 float 和 int 相加结果是 float?

c - Windows 上的 ANSI C 文件权限?

c - 在二叉树 (BT) 而非 BST 中搜索

c++ - 为什么 perror 在错误处理代码中没有广泛出现是有原因的?

c - 简单 C/GTK+ 软件上的随机段错误

android - 如何删除 textView 上的默认填充?

html - div中文本的奇怪填充/边距

jquery - 可以在 Jquery Mobile 中调整按钮填充吗?