1. Why memory alignment?

struct Struct1{ double a; // 8 bytes char b; // 1 byte int c; // 4 bytes short d; // 2 bytes}struct1;Copy the code

Memory access granularity: When the CPU reads memory, it reads it in chunks. The size of chunks can be 1, 2, 4, 8, 16… Bytes, such a block is memory read granularity

  • What would it look like to read the above data without memory alignment?

CPU when reading data, first of all read from the memory size 8 began to read, read a data, then use the same read granularity behind read data, found that b, c, d can’t read, so to modify memory read granularity, from 8 to 4, then read b contains c data, it is not right, memory access until modified particle size to 1, to read When reading c, the memory read granularity is not enough. You need to increase the granularity twice to 4 to read C…

From the above we can know that each time we read, we may have to adjust the granularity of memory read synchronously, so as not to read out of bounds, so that the CPU memory access speed will be greatly affected, the read time will be very long, and the risk of error will be very large.


2. Memory alignment rules

  1. Struct (struct) or union (union) data member, the first data member is placed at offset 0, each subsequent data member is storedThe starting positionStart with an integer multiple of the size of the member or its children
  2. If there are structure members in a structure, the structure members are taken from itAn integer multiple of the size of memory occupied by the largest internal member data typeTo store
  3. The total sizeof a structure, the result of sizeof, must be an integer multiple of its largest internal member

From the rules of memory alignment, let’s look at how the above structure aligns storage.

    1. double a

    By rule 1, the first data member, A, starts at offset 0 and occupies 8 bytes

    1. char b

    When stored in char B, the CPU reads the position of 8, which is an integer multiple of 1 (char is 1 byte) and can store a byte directly from the position of 8

    1. int c

    When storing to int C, the CPU reads to position 9, as per rule 1The starting location of the data member store is an integer multiple of the size of the member9 is not a multiple of the size of int (4), so the padding is 10, the padding is 11, and you don’t start storing int c until 12

    1. short d

    When stored to Short D, the CPU reads 16, which is an integer multiple of short’s size (2) and can be stored directly

So, the total size of the struct must be an integer multiple of its internal largest member according to rule 3, where the largest data member is double 8 bytes, and the last member data d is 17. Completes in multiples of the largest integer of 8 bytes, so the total size of this structure is 24 bytes.

When data is read after memory alignment, 8 memory read granularity is used to read A; When reading B and C, the memory read granularity 4 is changed only once. When reading B, 9, 10 and 11 are also read down. Although three bytes of memory are wasted, the efficiency of reading is also improved. Use space for time to optimize.


3. Attribute rearrangement optimization

struct Struct2{ double a; // 8 bytes int c; // 4 bytes short d; // 2 bytes char b; // 1 byte}struct2;Copy the code

Struct2 is exactly the same as Struct1, except in the order in which it is arranged. The following results are stored according to the same alignment rules:So Struct2 has a total size of 16 bytes.

It can be concluded that the internal memory size of the structure is related to the order of the memory size of the structure members

  • Case support

Here we see0x0000001300006261Pointer to garbled data, so person’sInt attributes age,char attributes C1, C2Where is it?

An OC object is essentially a structure

As we can see in the figure above, the age and char attributes of Person c1 and C2 are rearranged and optimized in a 16-bit data. The results of C1 and C2 are represented by ASCII codes.


Structure Extension 1:

struct Struct3{ double a; // 8 bytes char b; // 1 byte int c; // 4 bytes short d; // 2 bytes struct Struct1 STR; // }struct3;Copy the code

The Struct3 structure also contains the Struct1 structure, so how do you align memory?

The memory alignment of a, B, C, and D is the same as above. Here we focus on structure data member STR.

By memory alignment rule two:

If a structure has a structure member, the structure member is stored at an integer multiple of the memory size of the largest internal member data type. The largest data type in the Struct1 structure is double–8 bytes, stored to d at position 17. So when you store the first data double a in a Struct1 structure,18, 19, 20, 21, 22, 23 are all padding. Details are as follows:

The total size of a structure must be an integer multiple of its largest internal member. So the total size of the Struct3 structure is 48.


Structure Extension 2:

struct Struct1{
    char b;
    int c;
    short d;
}struct1;

struct Struct2{
    int c;
    double a;
    char b;
    struct Struct1 struct1;
    short d;
}struct2;
Copy the code

Struct2 contains struct1 as the data member, but not in the last position. Does it make a difference to store struct2 like this?

In struct2, the result of c, A, and B is stored to 16 bytes. Focus on how to store after analysis:

  1. By memory alignment rule 2: If a structure has a structure member, the structure member fromAn integer multiple of the size of memory occupied by the largest internal member data typeSo struct1 is where the storage startsNot from 17But from20Start. As follows:

Pay attention to

When the last data member short D is stored, it is not stored from 30, because there is no memory alignment inside the struct1.

  1. By memory alignment rule three:The total size of the struct must be an integer multiple of the largest internal member, which must be filled up. So when struct1 starts with4 bytes Maximum integer multiple complement, so the total size of struct1 is 12 bytes.

Then, the last data member of struct2, short D, is stored at [32,33] from 32. Also according to memory alignment rule 3, the total size of struct2 is 40 bytes after the completion of the maximum integer multiple of 8 bytes.





Data type table reference: