Turn from: http://www.cnblogs.com/longlybits/articles/2385343.html (with changes)
Memory alignment
when using the sizeof operator to find 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.
Alignment Policy
Use the following command to view the current packing alignment (default alignment parameters)
#pragma pack (show)
Rules for data alignment: Select small alignment in self-aligning parameters and specify alignment parameters
-Self-aligning parameters:
1) data member: The length of the byte that the type of the data member occupies
2) Complex data overall: (e.g. struct) the length of its largest data member N; offset must meet: offset%n = 0
-Specify the alignment parameters:
Precompiled instruction #pragma pack (...)
1) Function: Specifies the structure, union, and packing alignment of the class member; (Default alignment parameters)
2) Syntax: #pragma pack ([show], [Push | pop], [identifier], N)
3) Description:Pack provides data declaration level control, does not work with definitions , does not specify parameters when calling Pack, N will be set to default value;
4) Specific analysis:
1, show: Optional parameters, display the current packing aligment bytes, in the form of warning message is displayed;
2, push: Optional parameters, the current specified packing alignment value for the stack operation, where the stack is the internal compiler stack, while setting the current packing alignment is n; if n is not specified, The current packing alignment value is stacked;
3. Pop: optional parameter; Removes the topmost record from the internal compiler stack, or if n is not specified, the current stack top record is the new packing alignment value, and n will be the new packing if N is specified Aligment value; If identifier is specified, the record in the internal compiler stack will be popped until identifier is found, then the pop is Identitier, and the packing is set The alignment value is the record at the top of the current stack, and if the specified identifier does not exist in the internal compiler stack, the pop operation is ignored;
4, identifier: Optional parameters; When used with push, gives a name of the record that is currently pressed into the stack, and when used with a pop, from internal compiler All the record pops out of the stack until the identifier is popped out, and if the identifier is not found, the pop operation is ignored;
5, N: optional parameter; Specifies the value of the packing, in bytes, the default value is 8, and the valid values are 1, 2, 4, 8, 16, respectively.
Default condition
Win32 the default alignment parameter under 8,win64 is 16 (that is, double is the number of bytes).
So when you don't specifically specify alignment parameters, align the data by its own alignment parameters:
1) 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. So the size of the widest data type is used as the alignment parameter.
2) The offset of each member of the struct relative to the first address of the struct must be an integer multiple of the alignment parameter (offset%n = 0), and if necessary, the bytes are populated between the members. It is also possible to populate a number of bytes at the end of the last member so that the occupied space is an integer multiple of the widest data type size.
Chestnuts
Let's take a look at how sizeof calculates the size of the structure.
1.TEST1 Empty Structure body
typedef struct NODE{}S;
sizeof (s) =1 or sizeof (s) =0// takes up 1 bytes in C + + and 0 bytes in C.
2.test2
typedef struct node1{ int A; Char b; Short C;} S1;
sizeof (S1) =8//Because the longest data type in the struct node1 is int, which accounts for 4 bytes, and therefore is aligned in 4 byte, it is stored as follows:
|--------int--------| 4 bytes
|char|----|--short-| 4 bytes
3.test3
typedef struct node2{ char A; int b; Short C;} S2;
Siezof (S3) =12//Longest data type is int, accounting for 4 bytes. Therefore, the 4-byte alignment is stored in the following way:
|char|----|----|----| 4 bytes
|--------int--------| 4 bytes
|--short--|----|----| 4 bytes
4.TEST4 contains static data members
typedef struct node3{ int A; Short B; static int C;} S3;
sizeof (S3) =8//This structure contains static data members, while static data members are stored in the location and node It is independent of the storage address of the struct instance (note that static data members are not allowed in C + + in structs, whereas static data members are not permitted in the structure of the construct. The storage method is:
|--------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 5.TEST5 structure is contained in the body.
typedef struct node4{ bool A; S1 S1; Short B;} S4;
sizeof (S4) =16//s1 is 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 bytes:
|-------bool--------| 4 bytes
|-------S1----------| 8 bytes
|-------Short-------| 4 bytes
6.test6
typedef struct node5{ bool A; S1 S1; Double b; int C;} S5;
sizeof (S5) =32//s1 accounts for 8 bytes, while the longest data type in S1 is int, accounting 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
7.test7
If #pragma pack (n) is used in the program to force 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.
To cancel the force alignment, the command #pragma pack () is available, which restores to the default
If you use the command #pragma pack (4) at the beginning of the program, for the following struct body
typedef struct node5{ bool A; S1 S1; Double b; int C;} S5;
sizeof (S5) =24//Force is 4-byte aligned, while the longest data type in S5 is double, accounting for 8 bytes, and therefore 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
Summarize
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.
struct-Body byte alignment