【问题标题】:Use __attribute__((aligned())) in struct, why the result of sizeof is this?在struct中使用__attribute__((aligned())),为什么sizeof的结果是这样的?
【发布时间】:2016-07-26 09:31:05
【问题描述】:

这是我的测试代码:

#include <cstdio>
struct A {
    int  a;
    int  b;
    int  c __attribute__((aligned(4096)));
    int  d;
}t;
int main()
{
    printf("%d\n",sizeof(t));

    return  0;
}

结果是8192,但我不知道原因。

【问题讨论】:

    标签: c memory-management


    【解决方案1】:

    有一些关于结构对齐的事实值得一提:

    1. 类型的大小始终是其对齐方式的倍数。
    2. 结构的对齐方式始终是其所有成员的对齐方式的倍数。

    因此,由于其中一个成员的对齐方式为 4096,因此结构本身的对齐方式至少为 4096。很可能正是如此。

    但由于它需要在c 之前填充4080 字节,因此结构的大小至少为4104,但它必须是4096 的倍数,它的对齐方式。所以它增长到 8192。

    【讨论】:

      【解决方案2】:

      这是因为sizeof 告诉了数组中下一个元素的放置位置。那就是如果你有声明

      struct A a[2];
      

      您需要将a[0].ca[1].c 都与4096 字节对齐。

      严格来说,编译器可以通过4096 的大小来实现这一点,但这可能不是因为struct A 将继承对齐要求并在int 字段之前放置两个ints也必须对齐在.b.c之间插入4080ish字节的填充,然后在.d之后插入4080ish字节的填充。

      编译器可以做到这一点(无需重新排列结构成员)的方式是扩展对齐的概念。除了要求地址必须落在N*4096 形式的地址上之外,它还可以通过偏移量来扩展它,要求它落在N*4096-2*sizeof(int) 形式的地址上。提供struct A 这样的要求将导致.c 元素自然而然地变为4096 字节对齐,而无需在.b.c 之间进行填充(也)。

      【讨论】:

      • 编译器不能随意重新排列结构成员。 C 标准要求指向 a 的指针也是指向封闭对象的指针,因此以下是合法的:int* ptr = &amp;t.a; ((struct A*)ptr)-&gt;b = 42; 因此,编译器无法设法将给定的结构打包在 4096 内字节。
      • @cmaster 重新排列成员并不是使其在 4096 字节大小下工作的唯一方法。编译器可能还要求struct A 需要在4096 字节边界之前有一个地址2*sizeof(int)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      相关资源
      最近更新 更多