C++ 为 struct 成员分配的内存是否连续?如果结构成员是数组怎么办?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8377667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is the memory allocated for struct members continguous? What if a struct member is an array?
提问by smilingbuddha
In C/C++ suppose I define a simple struct named test
as follows.
在 C/C++ 中,假设我定义了一个名为test
如下的简单结构。
struct test
{
double height;
int age;
char gender;
}
For a specific instance of this struct say test A
are A.height, A.age, A.gender
contiguous
in memory?
对于此结构的特定实例,test A
是否A.height, A.age, A.gender
在内存中是连续的?
More generally, how do the layouts in memory for a Structure of Arrays and an Array of structures look like? A picture would be really helpful.
更一般地说,数组结构和结构数组在内存中的布局如何?一张照片真的很有帮助。
回答by Mysticial
They will not necessarily be contiguous in memory. This is due to struct padding.
它们在内存中不一定是连续的。这是由于struct padding。
However, in your particular case, it may very well be contiguous. But if you changed the order to something like this:
但是,在您的特定情况下,它很可能是连续的。但是如果你把顺序改成这样:
struct test
{
char gender;
int age;
double height;
}
then they most likely will not be. However, in your particular case, you will still likely get padding after gender
, to realign the struct to 8 bytes.
那么他们很可能不会。但是,在您的特定情况下,您仍然可能会在gender
,之后填充以将结构重新对齐为 8 个字节。
The difference between SoA (Struct of Arrays) and AoS (Array of Structs) would be like this:
(SOA之间的差值阵列的STRUCT)和AOS(结构的数组)会是这样:
SoA:
索A:
-----------------------------------------------------------------------------------
| double | double | double | *pad* | int | int | int | *pad* | char | char | char |
-----------------------------------------------------------------------------------
AoS:
服务范围:
-----------------------------------------------------------------------------------
| double | int | char | *pad* | double | int | char | *pad* | double | int | char |
-----------------------------------------------------------------------------------
Note that AoS pads within each struct. While SoA pads between the arrays.
请注意,AoS 填充在每个结构中。而 SoA 在阵列之间填充。
These have the following trade-offs:
这些有以下权衡:
- AoStends to be more readable to the programmer as each "object" is kept together.
- AoSmay have better cache locality if all the members of the struct are accessed together.
- SoAcould potentially be more efficient since grouping same datatypes together sometimes exposes vectorization.
- In many cases SoAuses less memory because padding is only between arrays rather than between every struct.
- 由于每个“对象”都保存在一起,因此AoS对程序员来说更具可读性。
- 如果结构体的所有成员一起访问,AoS可能具有更好的缓存位置。
- SoA可能会更有效,因为将相同的数据类型组合在一起有时会暴露矢量化。
- 在许多情况下,SoA使用较少的内存,因为填充仅在数组之间而不是在每个结构之间。
回答by Oliver Charlesworth
The individual fields are contiguous in the sense that there will be no other variables stored in-between them. They are also guaranteed to be stored in the order that you declared. But the compiler is free to insert padding in-between the individual fields to align things to word boundaries, for instance. So the following:
各个字段是连续的,因为它们之间不会存储其他变量。它们也保证按照您声明的顺序存储。但是,例如,编译器可以自由地在各个字段之间插入填充以将事物与字边界对齐。所以如下:
struct test
{
double height;
char gender;
int age;
};
may look like this in memory:
在内存中可能看起来像这样:
+7 +6 +5 +4 +3 +2 +1 +0
+---+---+---+---+---+---+---+---+
0x0000 | height |
+---+---+---+---+---+---+---+---+
0x0008 | age | |gen|
+---+---+---+---+---+---+---+---+
As for the difference between SoA and AoS, they're laid out exactly as you might imagine.
至于 SoA 和 AoS 之间的区别,它们的布局与您想象的完全一样。
回答by Jim Buck
Other than the standard disclaimer of "it depends on your platform, compiler, blahblahblah"... yes, height
, age
, and gender
will be contiguous in memory with no padding in between:
除了其它“这取决于你的平台,编译器,blahblahblah”标准免责声明......是的,height
,age
,并gender
会在内存中连续的,中间没有任何填充:
height|age|gender
height|age|gender
However, if you have an array of test
, each array element will have padding in between them after each's gender
so that the next element's height
is properly aligned.
但是,如果您有一个 数组test
,则每个数组元素之间都会在每个数组元素之后进行填充,gender
以便下一个元素height
正确对齐。
|height0|age0|gender0|padding0|height1|age1|gender1|padding1|...
|height0|age0|gender0|padding0|height1|age1|gender1|padding1|...
If your goal is to use the least amount of memory possible, then you should go with "structure of arrays" since it uses no padding.
如果您的目标是尽可能使用最少的内存,那么您应该使用“数组结构”,因为它不使用填充。
|height0|height1|...
|height0|height1|...
|age0|age1|...
|age0|age1|...
|gender0|gender1|...
|gender0|gender1|...