When using the sizeof operator to calculate the space occupied by a struct, it is not simple to add up the space of all the elements in the struct, which involves the problem of memory byte alignment. In theory, access to any variable can be accessed from any address, but in fact it is not, in fact, access to a specific type of variable can only be accessed at a specific address, which requires the individual variables to be arranged in space according to certain rules, rather than simply sequential arrangement, which is memory alignment.
Reasons for Memory alignment:
1) Certain platforms can only access certain types of data at specific addresses;
2) Increase the speed of data access. For example, some platforms each time the data is read from an even address, for a variable of type int, if it is stored from the even address unit, it can read the variable in only one reading period, but if it is stored from the odd address cell, it needs 2 read cycles to read the variable.
Microsoft C compiler alignment policy under the Win32 platform:
1) The first address of a struct variable can be divisible by the size of its widest data type member. When the compiler opens up space for a struct variable, it first finds the widest data type in the struct, and then looks for the location where the memory address can be divisible by the size of the data type, which is the first address of the struct variable. The size of the widest data type is used as the justification standard.
2) the offsets (offset) of each member of the struct relative to the first address of the struct are an integer multiple of the size of each member itself, and if necessary, the bytes are populated between the members. When the compiler opens up space for a struct member, first checks if the offset of the pre-open space is an integer multiple of the member's size, if it is, or if it is not, fills a number of bytes to achieve the requirement of an integer multiple.
3) The size of the space occupied by the structure variable must be an integer multiple of the widest data type size. If necessary, a number of bytes are populated at the end of the last member so that the occupied space is an integer multiple of the widest data type size.
Let's take a look at how sizeof calculates the size of the structure.
Test empty struct
Then sizeof (s) = 1; or sizeof (s) = 0;
Takes up 1 bytes in C + + and 0 bytes in C.
1.test1
typedef structnode1{ int a; char b; shortc;}S1; |
Then sizeof (S1) = 8. This is because the longest data type in the struct node1 is int, which accounts for 4 bytes and therefore is aligned in 4 bytes, the struct is stored in memory in the form of
|--------int--------| 4 bytes
|char|----|--short-| 4 bytes
Total 8 bytes
2.test2
typedef structnode2{ char a; int b; shortc;}S2; |
Then Siezof (S3) =12. The longest data type is int, accounting for 4 bytes. So in 4-byte alignment, the memory space is stored in the following way:
|char|----|----|----| 4 bytes
|--------int--------| 4 bytes
|--short--|----|----| 4 bytes
A total of 12 bytes
3.TEST3 contains static data members
typedef structnode3{ int a; short b; static intc;}S3; |
Then sizeof (S3) =8. This structure contains static data members, where static data members are stored regardless of the storage address of the struct instance (note that only the struct in C + + can contain static data members, whereas static data members are not allowed in the struct in C). It is stored in memory in the following ways:
|--------int--------| 4 bytes
|--short-|----|----| 4 bytes
The variable c is stored separately in the static data area, so it does not calculate the space occupied by C when calculating its size with siezof.
The structure of 4.TEST4 structure is contained in the body.
typedef structnode4{ bool a; S1 s1; shortb;}S4; |
Then sizeof (S4) = 16. is because S1 accounts for 8 bytes, while the longest data type in S1 is int, 4 bytes, bool Type 1 bytes, short is 2 bytes, and therefore is stored in 4-byte alignment.
|-------bool--------| 4 bytes
|-------S1----------| 8 bytes
|-------Short-------| 4 bytes
5.test5
typedef structnode5{ bool a; S1 s1; double b; intc;}S5; |
Then sizeof (S5) = 32. is because S1 accounts for 8 bytes, while the longest data type in S1 is int, which accounts for 4 bytes, and double is 8 bytes, so in 8-byte alignment, it is stored in the following way:
|--------bool--------| 8 bytes
|---------S1---------| 8 bytes
|--------Double------| 8 bytes
|----int----|---------| 8 bytes
6.test6
If the #pragma pack (n) command is used in the program to force an n-byte alignment, N is 8 by default.
Compares the byte size of the longest data type in n and struct, whichever is the same as the alignment standard.
If you want to cancel the force alignment, you can use the command #pragma pack ()
If you use the command #pragma pack (4) at the beginning of the program, for the following struct body
typedef structnode5{ bool a; S1 s1; double b; intc;}S5; |
Then sizeof (S5) =24. Because the force is 4-byte aligned, and the longest data type in S5 is double, which is 8 bytes, it is aligned in 4 bytes. The memory is stored in the following way:
|-----------a--------| 4 bytes
|--------S1----------| 4 bytes
|--------S1----------| 4 bytes
|--------B-----------| 4 bytes
|--------B-----------| 4 bytes
|---------C----------| 4 bytes
To summarize, the main points to note when calculating sizeof:
1) If the structure is empty, it will only account for 1 bytes of the unit
2) If all data types in the struct are the same, the space occupied is the member data type length x member number
If the data type in the struct is different, the space occupied by the longest data type member is the alignment standard, the data member contains another struct variable T, then the longest data type in T is compared with other data members, the longest is the alignment standard, but T is stored as a unit, just look at the other members.
3) If you use the #pragma pack (n) command to force the alignment criteria, take the smaller of the number of bytes in both N and the longest data type in the struct as the alignment standard.
In addition to the existence of alignment in the structure, the normal variable storage also has a case of byte alignment, that is, self-aligning. The compiler stipulates that the storage head address of a normal variable must be divisible by the data type width of the variable.
/*test sizeof operator 2017.10.25*/#include<iostream>using namespacestd;//#pragma pack (4)//set 4-byte alignment//#pragma pack ()//Cancel 4-byte alignmenttypedefstructnode{}s; typedefstructnode1{intA; Charb; ShortC;} S1; typedefstructnode2{CharA; intb; ShortC;} S2; typedefstructnode3{intA; Shortb; Static intC;} S3; typedefstructnode4{BOOLA; S1 S1; Shortb;} S4; typedefstructnode5{BOOLA; S1 S1; Doubleb; intC;} S5;
intMainintargcChar*argv[]) {cout<<sizeof(Char) <<" "<<sizeof( Short) <<" "<<sizeof(int) <<" "<<sizeof(float) <<" "<<sizeof(Double) <<Endl; s S; S1 S1; S2 S2; S3 S3; S4 S4; S5 S5; cout<<sizeof(S3) <<Endl; cout<<sizeof(s) <<" "<<sizeof(S1) <<" "<<sizeof(S2) <<" "<<sizeof(S3) <<" "<<sizeof(S4) <<" "<<sizeof(S5) <<Endl; return 0;}
A/C + + struct body byte alignment