结构内存中的布局.C/C++中的数组结构和结构数组

smi*_*dha 37 c c++ arrays struct

在C/C++中,假设我定义了一个名为point如下的简单结构.

struct test
{
double height;
int    age;
char   gender;
}
Run Code Online (Sandbox Code Playgroud)

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

更一般地说,对于阵列结构和结构数组,内存中的布局如何?一张照片真的很有帮助.

Mys*_*ial 63

它们在记忆中不一定是连续的.这是由于struct padding.

但是,在您的特定情况下,它可能是连续的.但是,如果您将订单更改为以下内容:

struct test
{
    char   gender;
    int    age;
    double height;
}
Run Code Online (Sandbox Code Playgroud)

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


(SOA之间的差值阵列的STRUCT)和AOS(结构的数组)会是这样:

SoA的:

-----------------------------------------------------------------------------------
| double | double | double | *pad* | int | int | int | *pad* | char | char | char |
-----------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

AOS:

-----------------------------------------------------------------------------------
| double | int | char | *pad* | double | int | char | *pad* | double | int | char |
-----------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

请注意,每个结构中的AoS焊盘.而阵列之间的SoA垫.

这些有以下权衡:

  1. 随着每个"对象"保持在一起,AoS往往对程序员更具可读性.
  2. 如果结构的所有成员一起被访问,则AoS可能具有更好的缓存局部性.
  3. SoA可能更有效,因为将相同数据类型组合在一起有时会暴露矢量化.
  4. 在许多情况下,SoA使用较少的内存,因为填充仅在数组之间而不是在每个结构之间.

  • 啊,好点.我看到OP已经定义了它们,但我没有意识到没有提到缩写AoS和SoA.(AoS =结构数组,SoA =数组结构) (3认同)

Oli*_*rth 8

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

struct test
{
    double height;
    char   gender;
    int    age;
};
Run Code Online (Sandbox Code Playgroud)

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

         +7  +6  +5  +4  +3  +2  +1  +0
        +---+---+---+---+---+---+---+---+
0x0000  |            height             |
        +---+---+---+---+---+---+---+---+
0x0008  |      age      |           |gen|
        +---+---+---+---+---+---+---+---+
Run Code Online (Sandbox Code Playgroud)

至于SoA和AoS之间的区别,它们的布局与您想象的完全一致.