When it comes to calculating the size of the structure, one of the problems involved is the number of Zimo
Computer systems Limit the location of basic types of data in memory , and they require that the value of the first address of the data be a multiple of a number k (usually 4 or 8), which is called memory alignment, and this K is referred to as the number of Zimo (alignment modulus) of the data type .
This means that the number of Zimo is the amount of space occupied by this data type.
On the calculation of the length of the structure, I checked, there are two ways to understand:
Way One:
When the ratio of one type S pair of Zimo number to the Zimo number of another type T is greater than 1 (the type S is stronger than T) , we call the alignment requirement of type S stronger (strict) than T, while the T is weaker than s (loose).
struct a{ short A; // k is 1 int B; // k is 4 char C; //k double D; // k is 8 }a;
ANSI c specifies that the size of a struct type is the sum of the size of all its fields and the size of the fill area between fields or the end of a field. The fill area is the extra space allocated to the struct for the structure field to meet the memory alignment requirements . The structure itself has an alignment requirement, and the ANSI C standard stipulates that the alignment requirements of the struct type cannot be more stringent than the one that is most stringent in all of its fields .
In other words, the modulus of the struct should be an integer multiple of the strongest field type modulus in the field.
So the above code corresponds to the memory layout diagram should be this:
If the int type is stronger than the sort type, the first address of the int variable should be a multiple of 4, and a double with a type stronger than char,double should be a multiple of 8.
Here, padding is the fill area, and notice that the fill area is the extra space allocated to the struct for the structure field to meet the memory alignment requirements. a fill area can only be generated when a member of a struct has an Zimo number of one type S that is inconsistent with the number of Zimo of another type T.
In the structure above, A and B are filled with two space, B is stronger than C, so B to C does not need to fill the space, C is already occupied 8 bytes, and C itself to have 1 bytes of space is the position then to 9, so C to D also fill 7 space, that is:
Print Address:
So, the size of the memory space that the struct a occupies should be 24.
But if you change the position of structure a:
struct b{ short// modulus is 2 char// modulus is 1 int // modulus is 4 double// modulus is 8}b;
Then the corresponding memory distribution has changed:
Printing results:
In conclusion, it can be concluded that:
- The variables are evaluated first. The position of a variable in a struct must be an integer multiple of the Zimo number, not an integer multiple, and the fill area will be allocated.
- The structure is then computed. The length of the structure is the Zimo number and the fill area .
At this point, however, consider the Zimo number of the struct itself (the struct is also the basic data type). His modulus is the modulus defined by the #pragma pack and the smaller of the member lengths of the largest basic data type within the structure. The length of the structure should be an integer multiple of the modulus.
As the following example
struct b{ int// modulus is 4 char// modulus is 1}b;
At this point, the total length of the variable in the struct is 5, and according to the idea above, the length of the struct should be a multiple of the strongest type int, or 4 * 2 = 8:
Yes, it is 8, however, if you add the Compile option #pragma pack preprocessing directives:
#pragma pack (push, 2)struct b{ int// modulus 4 Char // modulus is 1}b; #pragma pack (POP)
At this time member B's modulus should be 2-based, A is 1, less than 2, then continue to 1 of the Zimo number-based. But the modulus K of a struct should be the smaller of the numbers in the number of member lengths in which the compiled compilation option and the structure's internal data type are strongest, and here is 2, so a's length becomes 6 (multiples of 2):
In real-world development, you can change the alignment rules of the compiler by specifying the/zp compilation option or by using the #pragma pack directive in your code. For example, specifying/ZPN (n in VC7.1 can be 1, 2, 4, 8, 16) is telling the compiler that the maximum number of Zimo is n.
In this case, the alignment rules for all base data types that are less than or equal to n bytes are the same as the default, but the number of Zimo for data types greater than n bytes is limited to n. if n = 1, then the size of the structure is the sum of the size of each field , where the structure is defined in Moses, which can reduce the memory space occupied by the structure.
#pragma Pack (push, 1)struct b{ int// modulus 4 Char // modulus is 1}b; // the length of the struct variable B is now 5 #pragma pack (POP)
Way two:
- The variables are evaluated first. Based on the number of Zimo, the starting address in the structure variable must be an integer multiple of the Zimo number, not an integer multiple will be automatically padded.
- The structure is then computed. Calculates the size of a structure based on the number of Zimo. The Zimo number of a struct is the modulus defined by the #pragma pack and the smaller of the member length of the largest basic data type within the structure. The length of the structure should be an integer multiple of the modulus. (But note that if there is a preprocessing instruction definition, the modulus of the variable is greater than N, then the alignment rule of n is pressed)
In this way:
struct a{ short// modulus is 2 int// modulus is 4 Char// modulus is 1 double// modulus is 8}a;
1. First calculate the address of the member in the struct:
A: The address is 0, is a multiple of its modulus 2, so no longer.
B: If not aligned, the address is 2. is not an integer multiple of modulus, should be filled 2 space (in fact, the fill area of the mode one), the address becomes 4.
C: At this point the address is 8, which is an integer multiple of 1, no longer padded.
D: If not aligned, the address is 9. So 8 spaces should be filled, the address becomes 16
At this point the members occupy 24 of the space in the struct
You can also verify by printing the address:
2. Calculate the modulus of the structural body:
The compiler directive is not defined at this time, so the structure modulus should be the modulus of the maximum space type in its members, that is, 8, whose size is 24, which is a multiple of 8, so the struct is no longer aligned.
For both of these ways, I think the two ways may be better understood, but take into account the issue of compiling instructions, and finally come to the following:
1. When no compile instruction n is defined:
Structure length = The sum of space occupied by members in the structure (22 contrast);
It is then necessary to verify that the struct address is an integer multiple of the member's strongest type variable modulus K.
2. When the compile instruction n is defined:
If the type strength is less than n then the member's alignment rules are followed. If it is greater than n then the alignment rules of n are required.
It is also later to verify that the struct address is an integer multiple of the Zimo number. If not, the structure modulus is also aligned.
Length of the structure struts