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

3

51

In C/C++ suppose I define a simple struct named test as follows.

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?

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.

Birdsong answered 4/12, 2011 at 18:44 Comment(0)
C
81

They will not necessarily be contiguous in memory. This is due to 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.


The difference between SoA (Struct of Arrays) and AoS (Array of Structs) would be like this:

SoA:

-----------------------------------------------------------------------------------
| 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.

These have the following trade-offs:

  1. AoS tends to be more readable to the programmer as each "object" is kept together.
  2. AoS may have better cache locality if all the members of the struct are accessed together.
  3. SoA could potentially be more efficient since grouping same datatypes together sometimes exposes vectorization.
  4. In many cases SoA uses less memory because padding is only between arrays rather than between every struct.
Cloying answered 4/12, 2011 at 18:51 Comment(7)
I'm sorry, but what are those SoA and AoS you are explaining without defining them?Reductive
Ah, good point. I saw that the OP already defined them, but I didn't realize that the abbreviations AoS and SoA weren't mentioned. (AoS = Array of Structs, SoA = Structure of Arrays)Cloying
I'd add many compilers support removing padding with ` #pragma pack(1)`. Padding is there for good reason. Speed / Memory trade-offs involved.Hellenhellene
@Mysticial: Hello , I got into this and I wanted to ask you if you can.If I had a structure " struct { int v; int arr[ 5 ]; } " , would I have padding or not?Because both are int's.Thanks!Lysozyme
@Lysozyme Probably not for any system that exists today.Cloying
I am typically making a decision between readability and vectorization.Once
The SoA almsot certainly has no padding based on how you've presented it i.e arraof doubles first, then ints and finally chars.Machos
P
17

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.

Pasahow answered 4/12, 2011 at 18:46 Comment(0)
G
-1

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:

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.

|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|...

|age0|age1|...

|gender0|gender1|...

Goerke answered 4/12, 2011 at 18:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.