structa{intA; Charb; Shortc;};structb{CharA; intb; Shortc;};#pragmaPack (2)structc{CharA; intb; Shortc;};#pragmaPack (1)structd{intA; Charb; Shortc;};int_tmain (intARGC, _tchar*argv[]) {cout<<sizeof(A) <<" "<<sizeofB <<" "<<sizeofC <<" "<<sizeofD <<Endl; return 0;}The results of the operation are as follows: 8 12 8 7
Theoretically, the size of the struct A and B should be the same, and this is caused by byte alignment.
2. Why should byte alignment be? Simply put: To improve access efficiency. bytes are the smallest unit of memory space allocation, and in a program, the variables we define can be placed in any location. In fact, the CPU of different architectures is regular when accessing certain types of variables, for example, when some CPU accesses int type variable, it reads from even address, and int type occupies 4 bytes (Windows platform). 0x0000,0x0004,0x0008 ..... This allows you to read the value of the INT type variable only once. Conversely, you need to read two times, and then combine high and low bytes to get the value of the int type, which, of course, increases the efficiency of access. Usually when writing a program, there is no need to consider these situations, and the compilation will consider these cases for us, unless the CPU programming for those special architectures needs to be considered. Of course, users can also manually control the alignment. 3. Compiler rules for byte alignment
I have explained some of the principles of compiler-to-byte processing from the following three articles. Of course, in addition to some special compiler in the processing of byte alignment is not the same, these conditions I have not met, do not explain.
A.about the alignment value of the data type itself, the different types are aligned according to different bytes.
| Type |
Alignment value (bytes) |
| Char |
1 |
| Short |
2 |
| Int |
4 |
| Float |
4 |
| Double |
4 |
B.the self-aligning byte value of a class, struct body。 For the alignment of struct types to class objects: aligns with the largest aligned byte in the member. For example, in struct A, the aligned byte of int A is 4, which is larger than char,short, so the alignment byte of a is 4 C.Specify the alignment byte value。 means the alignment value specified using the macro #pragma pack (n)
D. valid alignment byte values for classes, structs, and members. Valid alignment value =min (the class/struct/member's self-aligning byte value, specifying the alignment byte value).
A valid alignment value determines how the data is stored, and the sizeof operator calculates the member size based on the valid alignment value. In simple terms, effective alignment is actually a requirement that the address value stored by the data member be divisible by a valid alignment value, that is: the address value% valid alignment value =0
4. Combine the compiler analysis example to analyze the size of struct a based on the above principles. Member memory allocations for structs are analyzed in the order in which they are defined. struct A
{
int A;
Char b;
Short C;
For the sake of simplicity, I assume that the starting address for struct a access is 0x0000 without specifying an alignment value, the parse step:Step 1: According to the second article, first select the alignment value for the structure: Select the largest alignment value in the member, that is, int a, the alignment value is 4
Step 2: Again in accordance with principle fourth, determine the effective alignment value: that is, if you do not manually specify the alignment value, the default value is used: 4 (Windows 32 platform)
Step 3:int A valid address value =min (for 0x0000%4=0) so that the address of a is from 0x0000~0x0003
Step 4:char B Valid Alignment value =min (1,4), the address in turn from 0x0004 (because Ox0004%1=0), the allocation of a byte, the address segment allocation is: 0x0000~0x0004
The effective alignment value of step 5:short C =min (2,4), in theory, the assigned address should be continuous (from 0x0005~0x00006), but due to the need to consider the alignment of the case, the request address segment offset, so that from the 0x0006 (offset+ 1, because 0x0006%2=0) begins, allocates 2 bytes of address 0x0006~0x0007.
So far, the allocation of the address segment is: 0x0000~0x0007 such sizeof (a) size =0x0000~0x0007 a total of 8 byte size, while the 8%4=0 guarantees the address segment of struct A and 40% even multiple times.
Next, we analyze the size of struct B, and also assume that the starting address of struct B is 0x0000, and the following steps are analyzed:
struct B
{
Char A;
int b;
Short C;
}Step 1: True struct B Alignment value: Select the largest alignment value in the member, that is, int a, the alignment value is 4
Step 2: Determine the manually specified alignment value, using the default value: 4 (Windows, VC6.0 platform)
Step 3:char A valid address value =min (1,4), the address of A is 0X0000 (because 0x0000%1=0)
The effective alignment value of step 4:int b =min (+), the address in turn from 0x0004~0x0007 (because Ox0004%1=0), the allocation of 4 bytes, the current distribution of J address segment is: 0x0000~0x0007
The effective alignment value of step 5:short C =min (2,4), C, starts at 0x0008~0x0009 (because of 0x0008%2=0), and offsets the address 0x0006~0x0007 of 2 bytes.
To stop, the allocation of the address segment is: 0x0000~0x0009 A total of 10 bytes, but the alignment value of struct B is 4, which requires the address lot to be offset by 2 bytes, so that is from 0x0000~0x000b Total 12 (because 12%4=0) byte size. In this way, sizeof (B) =12
To use pragma to manually change the byte alignment value, first look at the definition of struct C:
#pragma pack (2)
struct C
{
Char A;
int b;
Short C;
};
In the code, the alignment value is manually specified as 2 bytes, and the analysis steps are as follows:
Step 1: Determine the structure C alignment value: Select the largest alignment value in the member, that is, int a, the alignment value is 4
Step 2: Determine the manually specified alignment value, using the manually specified value: 2
Step 3:char A valid address value =min (because 0x0000%2=0), so the address of A is 0x0000
Step 4:int B Valid Alignment value =min (4,2), the address in turn from 0x0002~0x0005 (because Ox0002%2=0), the allocation of 4 bytes, the current address segment allocation is: 0x0000~0x0005
The effective alignment value of step 5:short C =min (2,2), because of the need to consider the alignment, starting from 0x0006 (because of 0x0006%2=0), allocate 2 bytes of address 0x0006~0x0007
So far, the allocation of the address segment is: 0x0000~0x0007 A total of 8 bytes, but also to ensure the alignment of the struct C (2 byte alignment, pragma (2)), sizeof (C) =8
Note that this is different from struct B, where the sizeof size of B is 12 bytes, and the sizeof size of C is 8 bytes.
Finally analysis #pragma pack (1) This situation is very simple, the alignment value is 1, because 1 can be divisible by any data, so the member variable access order of struct D is continuous, so it is good, sizeof (D) =sizeof (int) +sizeof ( Char) +sizeof (short) =4+1+2=7 (e.g. from 0x0000~0x0006)
Summarize
Be careful when considering byte alignment, make clear several important concepts, such as the type itself alignment value, the manual alignment value and the valid alignment value, the effective alignment value determines the last access method, the effective alignment value equals the type itself alignment value and the manual alignment value the smaller one. Understanding this, the sizeof operator is fully aware of the operation of the type or the struct.
"Turn from" http://www.cnblogs.com/repository/archive/2011/01/13/1933721.html
byte alignment analysis in C + +