在C / C ++中假设我定义了一个名为point
的简单结构,如下所示。
struct test
{
double height;
int age;
char gender;
}
对于此结构的特定实例,test A
A.height, A.age, A.gender
是连续的
在记忆中?
更一般地说,对于阵列结构和结构数组,内存中的布局如何?一张照片真的很有帮助。
答案 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 :(得分: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”......是的,height
,age
和gender
在内存中是连续的,没有填充介于两者之间:
height|age|gender
但是,如果您有一个test
数组,则每个数组元素在每个gender
后面都会有填充,以便下一个元素的height
正确对齐。
|height0|age0|gender0|padding0|height1|age1|gender1|padding1|...
如果您的目标是使用尽可能少的内存,那么您应该使用“数组结构”,因为它不使用填充。
|height0|height1|...
|age0|age1|...
|gender0|gender1|...