堆分配变量的结构成员对齐

Posted

技术标签:

【中文标题】堆分配变量的结构成员对齐【英文标题】:Alignment of structure members for heap allocated variables 【发布时间】:2012-08-21 14:16:38 【问题描述】:

我有一个结构,其中成员有一定的对齐要求,而结构本身不存在这样的要求。

我正在使用 gcc,所以使用 __attribute__((aligned(n))) 可以解决问题,除非(据我所知)结构的实例是在堆上分配的。

如何保持堆分配实例的对齐? posix_memalign(3) 将对齐结构本身,而不是结构成员,所以我看不出如何使它与该函数一起工作。

来源在这里:https://github.com/colding/disruptorC/blob/master/src/disruptor.h#L92

【问题讨论】:

如果结构正确对齐,成员也会对齐。 如果将结构对齐到成员对齐的最大值,应该没问题,不是吗? 【参考方案1】:

无论结构在哪里——堆栈或堆——结构的布局必须相同。编译器确保sizeof() 和结构中元素的布局符合对齐要求(通过填充)。它还为结构本身提供了所需的对齐方式,以便其成员最终位于右边界(该值是其所有成员中最大的对齐方式)。

所以只需使用posix_memalign 就可以了:

MyStruct* ptr;
posix_memalign(&ptr, alignof(MyStruct), sizeof(MyStruct));

例如,如果你有这样的定义:

struct MyStruct 
    char c;
    double d;

当然,这取决于编译器,但最可能的行为是编译器会列出以下内容:

1 字节字符 7 字节的填充 8 字节双精度

并为整个事物提供 8 个字节的对齐方式。然后,如果结构本身正确对齐(在 8 字节边界上),则偏移 8 字节的双精度也将正确对齐。

alignof 在不同的编译器/标准中是不同的:gcc 中的__alignof__,MSVC 中的__alignof,C11/C++11 中的alignof。)

【讨论】:

是的,但我试图确保各个成员至少在缓存行大小偏移上对齐。因此,例如 double 或 char 的自然对齐将不足以确保这些成员在缓存行大小偏移上对齐,即使结构本身也是如此。 它适用于对齐和自然对齐。如果您的成员使用__attribute__((aligned(n))) 声明,则适用。 啊,好的。我认为对于堆上的实例,对齐属性被完全忽略了。如果不是这样,那么我没有问题。谢谢。 @colding 关键是结构的布局无论在哪里都是相同的。因此,如果编译器使用了一些魔法使其在堆栈上正确对齐,并且您以与它相同的方式按摩起始地址,那么它必须正常工作。

以上是关于堆分配变量的结构成员对齐的主要内容,如果未能解决你的问题,请参考以下文章

c语言中,系统为结构类型变量所分配的内存空间大小如何确定?

内存变量边界对齐

字节对齐1

C语言结构体

在C中为结构指针数组成员分配地址

c语言自定义类型——结构体,位段(匿名结构体,结构体的自引用,结构体的内存对齐)