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

时间:2011-12-04 18:44:15

标签: c++ c arrays struct

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

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

对于此结构的特定实例,test A A.height, A.age, A.gender是连续的 在记忆中?

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

3 个答案:

答案 0 :(得分:63)

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

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

struct test
{
    char   gender;
    int    age;
    double height;
}
然后他们很可能不会。但是,在您的特定情况下,您仍可能在gender之后进行填充,以将结构重新对齐为8个字节。


SoA(阵列结构)和AoS(结构数组)之间的区别如下:

<强> SoA的:

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

<强> AOS:

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

请注意每个结构中的AoS焊盘。虽然SoA在阵列之间填充。

这些有以下权衡:

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

答案 1 :(得分:7)

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

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

在内存中看起来像这样:

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

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

答案 2 :(得分:0)

除了标准免责声明“这取决于你的平台,编译器,blahblahblah”......是的,heightagegender在内存中是连续的,没有填充介于两者之间:

height|age|gender

但是,如果您有一个test数组,则每个数组元素在每个gender后面都会有填充,以便下一个元素的height正确对齐。

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

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

|height0|height1|...

|age0|age1|...

|gender0|gender1|...