为结构成员分配的内存是连续的吗?如果struct成员是数组呢?

Is the memory allocated for struct members continguous? What if a struct member is an array?

本文关键字:成员 如果 struct 结构 数组 内存 连续 分配      更新时间:2023-10-16

假设我在C/c++中定义了一个名为test的简单结构体,如下所示。

struct test
{
   double height;
   int    age;
   char   gender;
}

对于这个结构体的特定实例,说test AA.height, A.age, A.gender连续的在内存中?

更一般地说,数组结构体和结构体数组在内存中的布局是怎样的?照片会很有帮助的。

它们在内存中不一定是连续的。这是由于结构体填充。

但是,在您的特殊情况下,它很可能是连续的。但是如果你把顺序改成这样:

struct test
{
    char   gender;
    int    age;
    double height;
}

那么他们很可能不会。但是,在您的特殊情况下,您仍然可能在gender之后获得填充,以将结构体重新对齐为8字节。


SoA (Struct of Arrays)和AoS (Array of Structs)之间的区别是这样的:

SoA:

-----------------------------------------------------------------------------------
| double | double | double | *pad* | int | int | int | *pad* | char | char | char |
-----------------------------------------------------------------------------------

《超能:

-----------------------------------------------------------------------------------
| double | int | char | *pad* | double | int | char | *pad* | double | int | char |
-----------------------------------------------------------------------------------

请注意,每个结构中都有AoS。而SoA填充在数组之间。

它们有以下权衡:

  1. AoS对于程序员来说更容易读,因为每个"对象"都放在一起。
  2. AoS可能有更好的缓存局域性,如果所有的结构体成员被一起访问。
  3. SoA可能更有效,因为将相同的数据类型分组在一起有时会暴露向量化。
  4. 在许多情况下SoA使用更少的内存,因为填充只是在数组之间,而不是在每个结构体之间。

各个字段是连续的,因为它们之间不会存储其他变量。它们也保证按照您声明的顺序存储。但是编译器可以自由地在各个字段之间插入填充,例如,将内容与单词边界对齐。所以如下:

struct test
{
    double height;
    char   gender;
    int    age;
};

在内存中可能看起来像这样:

         +7  +6  +5  +4  +3  +2  +1  +0
        +---+---+---+---+---+---+---+---+
0x0000  |            height             |
        +---+---+---+---+---+---+---+---+
0x0008  |      age      |           |gen|
        +---+---+---+---+---+---+---+---+

至于SoA和aop之间的区别,它们的布局与您想象的完全一样。

除了标准的免责声明"这取决于你的平台,编译器,等等"…是的,height, agegender将在内存中连续,中间没有填充:

height|age|gender

然而,如果你有一个test的数组,每个数组元素在gender之后都有填充,以便下一个元素的height正确对齐。

|height0|age0|gender0|padding0|height1|age1|gender1|padding1|...

如果你的目标是使用尽可能少的内存,那么你应该使用"数组结构",因为它不使用填充。

|height0|height1|...

|age0|age1|...

|gender0|gender1|...

相关文章: