Memory space allocation and byte alignment of struct, and byte alignment of structure Allocation
Memory alignment
I:
1. What is memory alignment?
Suppose we declare two variables at the same time:
Char;
Short B;
Use the & (take the address symbol) to observe variable,
B address, we will find (taking 16-bit CPU as an example ):
If the address of a is 0x0000, the address of B is 0x0002 or 0x0004.
So there is such a problem: the address 0x0001 is not used, so what does it do? The answer is that it is not used. Because each time the CPU reads data from a memory address of 2 bytes (16-bit CPU) or 4 bytes (32-bit CPU) integer times. If the address of variable B is 0x0001, the CPU needs to read a short from 0x0000 first, and put its 8-Bit High into B's 8-bit low, then read the next short from 0x0002 and put its low 8 bits into the high 8 bits of B. In this way, in order to obtain the value of B, the CPU needs to perform two read operations.
However, if the IP address of B is 0x0002, the CPU only needs one read operation to obtain the value of B. Therefore, in order to optimize the code, the compiler usually specifies the proper position of the variable based on its size, that is, memory alignment (memory alignment for variable B, memory between a and B is wasted, and a does not occupy more memory ).
2. Structure memory alignment rules
The memory occupied by the struct is related to the declared sequence of its members in the struct. The memory alignment rules of its members are as follows:
(1) Each member is aligned based on its own number of alignment bytes and PPB (the number of alignment bytes specified, which is 4 by default for 32-bit servers), which minimizes the length of two bytes.
(2) The default alignment of complex types (such as structures) is the alignment of its longest member, so that the length can be minimized when the member is a complex type.
(3) The length after the structure alignment must be an integer multiple of the largest alignment parameter (PPB) in the member, so that the boundary alignment of each item can be ensured during Array Processing.
(4) Calculate the memory size of the struct. The offset addresses of each member should be listed, the length = the offset address of the last member + the length of the last member + the adjustment parameter of the last member (considering PPB ).
The following is an example of the above rules:
# Include # pragma pack (2) // specify PPB as 2 struct T {char a; // offset address 0int B; // offset address 2 char c; // offset address 6 };# pragma pack () // restore the original default PPB, with a 32-bit 4int main (int argc, char * argv []) {printf ("sizeof (struct T); return 0 ;}
The output result is 8. Statement # pragma pack (2) specifies that the struct is aligned in 2 bytes, that is, PPB = 2. The analysis is as follows:
Variable a is 1 byte by default, PB = 2, so a is aligned by 1 byte, And the offset address of a is 0.
By default, variable B is 4 bytes (int Is 4 bytes in 32-bit machines) and PB is 2. Therefore, B is aligned by 2 bytes, and B's offset address is 2.
The default value of variable c is 1 byte, PB = 2, so c is aligned by 1 byte, And the offset address is 6.
In this case, the number of bytes calculated by the struct is 7 bytes. Finally, according to rule 3, the number of bytes after the structure is aligned is 8. Sizeof (T) = 6 + 1 + 1 = 8
3. Example
(1) # pragma pack (2) // specify PPB as 2
Struct T {char a; // offset address 0 char B; // offset address 1int c; // offset address 2 };
Sizeof (T) = offset address of the last member + Length of the last member = 2 + 4 = 6.
Struct T1 {char a; // offset address 0 char B; // offset address 1int c; // offset address 4}; struct T2 {char; // offset address 0int B; // offset address 4 char c; // offset address 8 };
PPB = 4, then sizeof (T1) = 4 + 4 = 8; sizeof (T2) = 8 + 1 = 9, 9 cannot be divided into 4, so the number of adjustments is 3, that is, sizeof (T2) = 8 + 1 + 3 = 12
4. Notes
(1) byte alignment depends on the compiler;
(2) Pay attention to the PPB size, which is specified by the pragam pack (n;
(3) The number of bytes occupied by the struct must be divisible by PPB.
II:
(1) sizeof can also be used to evaluate a function call. The result is the size of the function return type, and the function will not be called.
(2) finally understand the memory allocation problem of the struct. The following principles apply to the byte alignment of each member in the struct: You can use the following principles to determine the size of the struct.
1. The offset of each member of the struct to the first address of the struct is an integer multiple of the size of the member. If necessary, the compiler will add the internaladding between the members );
For example, the following struct is used:
structex {int i;char t;int n;};
The offset of the 1st members is 0, which is an integer multiple of the size of the int Member 4 (assuming that the integer length of this machine occupies 4 bytes.
The size of the 2nd member t is char and 1. Assume that no Bytes are filled between member I and t, Because I is an integer, before the four bytes are filled, the offset of the 2nd member t to the struct is 4, which is 4 times the size of the t member 1, therefore, when the system allocates memory to the 2nd members of the struct, it does not fill in bytes between I and t to achieve the purpose of alignment.
When a struct has 3rd Members of n, it is first found that it is an integer data with a size of 4. Before it is not filled, the offset of n to the first address of the struct is: the first two members + fill byte = 5, so when the system finds that 5 is not an integer multiple of 4 (member size), it will be after Member t (or before n) fill 3 bytes so that the offset of n reaches 8 and is an integer multiple of 4. In this case, the memory occupied by this struct is 4 + 1 + 3 + 4.
2. The total size of the struct is an integer multiple of the size of the widest basic type of the struct. If necessary, the compiler will add the padding byte (trailingpadding) after the last member ).
After the above struct memory is allocated, check whether this condition is met. If the last Member does not need to be filled with the number of bytes, the size of this struct is 12. The largest and most basic type member of the ex struct is int, and the size of 4 is an integer multiple of 4. Therefore, you do not need to add the padding byte after the last member. So sizeof (ex) = 12;
If a struct is as follows:
struc test1 {int i;char t;int n;char add;};
So sizeof (ex1) = 16; the reason is that the last member is filled with three bytes.
3. There is an additional condition: the first address of the struct variable can be divisible by the size of its widest basic type member;
4. When determining the widest basic type member for a composite struct that contains the struct variable in the struct member attribute, it should include the child members of the composite type member. However, when determining the offset of a composite member, the composite type is regarded as a whole.
5. The formula is concluded that the size of the struct is equal to the offset of the last member plus the size of the struct plus the number of Padding Bytes at the end, that is:
Sizeof (struct) = offsetof (last item) + sizeof (trailing padding)