What is coordination and why:
The memory space of modern computers is divided by bytes. Theoretically, it seems that access to any type of variable can start from any address, but in reality, when accessing a specific variable, it is often accessed at a specific memory address, which requires all types of data to be arranged in space according to certain rules, rather than being discharged one by one. This is alignment.
The function and reason of alignment: The processing of storage space on each hardware platform is very different. Some platforms can only access certain types of data from certain addresses. Other platforms may not have this situation, but most commonly, if the data storage is not aligned according to the requirements suitable for its platform, it will bring the loss of access efficiency. For example, on some platforms, every reading starts with an even address. If the int type (assuming a 32-bit system) is stored at the beginning of an even address, it can be read in one reading cycle, while if it is stored at the beginning of an odd address, it may take two reading cycles, and the high and low bytes of the two reading results can be spliced together to get the int data. Obviously in reading effect.
The ratio has dropped a lot. This is also a game between space and time.
Realization of alignment
Usually when we write a program, we don't need to consider the alignment problem. The compiler will choose the alignment strategy suitable for the target platform for us. Of course, we can also tell the compiler to pass precompiled instructions and change the alignment of the specified data.
But because we generally don't need to care about this problem, we often get confused about some problems because the editor aligns the data storage and we don't understand it. The most common result is the sizeof result of struct data structure, which is unexpected. To this end, we need to understand the alignment algorithm.
Alignment algorithm:
Let the structure be defined as follows:
Structure a
{
int a;
char b;
Short c;
};
Structure A contains an int with a length of 4 bytes, a char with a length of 1 byte and a short data with a length of 2 bytes. So the space used by A should be 7 bytes. But because the compiler must align data members in space.
So the value of sizeof (strkuta) is 8.
Now adjust the structure according to the order of the member variables.
Structure b
{
char b;
int a;
Short c;
};
At this time, it is also a variable with 7 bytes, but the value of sizeof(struct B) is 12.
Next, we use the precompiled instruction #progma pack (value) to tell the compiler to use the alignment value we specified instead of the default value.
#progma pack (2) /* Specify 2-byte alignment */
Structure c
{
char b;
int a;
Short c;
};
#progma pack () /* Unassign alignment and restore default alignment */
The value of sizeof (structure c) is 8.
Modify the alignment value to 1:
#progma pack (1) /* specifies that it is aligned by 1 byte */
Structure d
{
char b;
int a;
Short c;
};
#progma pack () /* Unassign alignment and restore default alignment */
Sizeof (structure d) value is 7.
For char data, its self-alignment value is 1, for short data is 2, and for int, float and double data, its self-alignment value is 4, unit byte.
There are four conceptual values:
The alignment value of 1. data type itself: it is the self-alignment value of the basic data type explained above.
2. Specify the alignment value when specifying the alignment value: #progma pack (value).
3. Self-aligned value of a structure or class: the value with the largest self-aligned value among its members.
4. Effective alignment value of data members, structures and classes: the smaller of self-alignment value and specified alignment value.
With these values, we can easily discuss the members of a specific data structure and their own alignment. The effective alignment value n is the most important value ultimately used to determine the data storage address. The effective alignment of n is "alignment on n", that is to say, "storage start address %N=0" of data, and the data variables in the data structure are all discharged in the defined order. The starting address of the first data variable is the starting address of the data structure. The member variables of the structure should be aligned and discharged, and the structure itself should be rounded according to its effective alignment value (that is, the total length of the member variables of the structure needs to be an integer multiple of the effective alignment value of the structure, as understood in the following example). So you can't understand the value of the above example.
Case study:
Analysis example b;
Structure b
{
char b;
int a;
Short c;
};
Assume that B starts to discharge from address space 0x0000. The specified alignment value is not defined in this example. In my environment, this value defaults to 4. The self-alignment value of the first member variable b is 1, which is smaller than the specified or default alignment value of 4, so its effective alignment value is 1, so its storage address 0x0000 conforms to 0x0000% 1=0. The second member variable A has its own alignment value of 4, so its effective alignment value is also 4, so it can only be stored at the starting address of 0x0000. The third variable c has its own alignment value of 2, so the effective alignment value is also 2, which can be stored in the two word spaces of 0x0008 to 0x0009, which accords with 0x0008%2=0. So from 0x0000 to 0x0009, all the contents are B. Look at the self-alignment value of data structure B, which is the largest alignment value in its variables (here, B), so it is 4, so the effective alignment value of the structure is also 4. According to the requirements of structural roundness, 0x0009 to 0x0000= 10 bytes, (10+2)% 4 = 0. Therefore, 0x0000A to 0x0000b are also occupied by structure B. So b has 12 bytes from 0x0000 to 0x0000 b * *, and size of (struct b) =12;
Similarly, analyze the above example c:
#progma pack (2) /* Specify 2-byte alignment */
Structure c
{
char b;
int a;
Short c;
};
#progma pack () /* Unassign alignment and restore default alignment */
The self-alignment value of the first variable b is 1, and the specified alignment value is 2, so its effective alignment value is 1. Suppose that C starts from 0x0000, then B is stored at 0x0000, which is consistent with 0x0000% 1= 0; The second variable, with its own alignment value of 4, the specified alignment value of 2 and the effective alignment value of 2, is stored in four consecutive bytes, namely 0x0002, 0x0003, 0x0004 and 0x0005, which conforms to 0x0002%2=0. The self-alignment value of the third variable c is 2, so the effective alignment value is 2, which is stored in order.
In 0x0006 and 0x0007, it conforms to 0x0006%2=0. Therefore, from 0x0000 to 0x00007***, the variable of c is stored. The self-alignment value of C is 4, so the effective alignment value of C is 2. In addition, 8% 2 = 0, and c only takes up 8 bytes from 0x0000 to 0x0007. So sizeof(struct C)=8.