Question: Do the following two structures occupy the same amount of memory, only with different member locations?

struct LCStruct1 { double a; // 8 bytes char b; // 1 byte int c; // 4 bytes short d; // 2 bytes}struct1; struct LCStruct2 { double a; // 8 bytes int c; // 4 bytes char b; // 1 byte short d; // 2 bytes}struct2; NSLog(@"struct1 sizeof = %lu; struct2 sizeof = %lu",sizeof(struct1),sizeof(struct2));Copy the code

The memory alignments of memory alignments of memory alignments of memory alignments of memory alignments of memory alignments

What is memory alignment

Memory alignment, also known as byte alignment.

Memory space in the modern computers are divided according to the byte, theoretically seems to access to any type of variables can be from any address, but the reality is when they visit a specific type variables are often in a particular memory address access, which requires all kinds of data according to certain rules in space arrangement, Instead of sequentially placing one after the other, this is called alignment.

For a simple example, on a 64-bit system, int is 4 bytes and char is 1 byte. If they were placed in a structure, the memory size would be 4 + 1 = 5 bytes. In fact, in the Xcode environment, sizeof always results in 8 bytes:

Why memory alignment

There are two reasons for memory alignment:

  • Platform reason: Storage space is processed differently by hardware platforms. Some platforms can only access certain types of data from certain addresses. For example, in architectures where the CPU has an error when accessing an unaligned variable, programming must ensure byte alignment.

  • Performance Cause: Memory alignment improves access efficiency. For example, on some platforms each read starts at an even address. If an int (assuming a 32-bit system) is stored at the beginning of an even address, it takes one read cycle to read the 32 bits. If an int is stored at the beginning of an odd address, it takes two read cycles. The 32bit data is obtained by piecing together the high and low bytes from the two readings.

Rules of alignment

1. Data membersAlignment rules:Structure (struct).(orUnion (union)),The first data member is placed at offset 0.In the future, each data member store starts from the size of the member or the size of the member's children(As long as the member has children, such as arrays, structs, etc.)Start with an integer multiple of(For example, if int is 4 bytes, it starts with an integer multiple of 4.

2. The structure of the bodyAs a member: If a structure has someStructural member, the members of the structure are to be taken fromInteger multiples of the maximum internal element size(struct a contains struct b, b contains char,int,double, etc.)

3. The total sizeof a structure, which is the result of sizeof, must be an integer multiple of its largest internal member. What is lacking must be made up.

4. If in the program#pragma pack(n) precompiled instructions, all members are alignedN bytesPrevail (that is, the offset is an integer multiple of n), no longer consideredThe current typeAs well asThe largest type in the structure

Fourth, practice and verification

The above two struct objectsstudent1andstudent2Member variables of the same type, but in different order, the final size of memory space (unit: bytes) is not the same.sizeof(struct1) = 24.sizeof(struct2) = 16

Taking struct1 as an example,

The first member, a, is of type double and takes up 8 bytes with an offset of 0

The second member, b, is of type CHAR and occupies 1 byte space. According to rule 1, the offset of b must be an integer multiple of the size of type CHAR. The current offset is 8, which is an integer multiple of the size of type CHAR, so b follows a immediately.

The third member variable, c, is of type int and takes up 4 bytes. Rule 1 requires c to be an integer multiple of type int, so the compiler inserts a 3-byte buffer after b to ensure that c’s offset (12 bytes) is an integer multiple of type C (currently it is exactly 3 bytes).

The fourth member D is of short type and occupies 2 bytes. At this time, the offset of D is exactly 16 bytes, which is an integer multiple of the size of short. Therefore, there is no need to fill buffer bytes between C and D.

However, in this case, the size of a struct1 is 18 bytes. According to rule 3, the size of a strucT1 must be an integer multiple of its maximum member type double. Therefore, 6 bytes should be filled in addition to the 18 bytes to ensure that the final size of the struct1 is 24 to comply with Rule 3.

Similarly, we can obtain the memory distribution of struct2:

The advanced

To be continued…

Refer to the link

  1. My view on memory alignment rules
  2. C/C++ memory alignment
  3. How to understand memory alignment of structs?
  4. Master Cooci