Byte alignment
introduction
Byte alignment, one of the products of time in exchange for space. It means that when variables are accessed, a space is placed between different types of variables to perform so-called "alignment" operations on data, so as to improve the speed of program access to data and save time. It is mainly used in structures. Therefore, most structures will have different space sizes depending on the order of variable declaration or different platforms. So how to correctly calculate the size of a structure's space becomes a headache In the following, we will introduce in detail the understanding of byte alignment and the calculation of space size in the following different situations.
background
The memory space in modern computers is divided according to BYTE. In theory, it seems that access to any type of variable can be developed from any address, but in practice, it is often accessed at a specific memory address when accessing a specific type of variable. This requires various types of data to be arranged in space according to certain rules, rather than being placed next to each other, which is the so-called pairing.
Calculation
Regarding the calculation of byte alignment, we mainly need to grasp the following four basic operating rules:
1. The basic data type itself and its value
2. The specified alignment value of the program
3. The self-alignment value of the
custom type 4. The self-alignment value of the custom type Effective alignment value
The following is a discussion of the application of these principles with some specific cases
Rule one, the basic data type itself and its value
We all know that each type of data has its own space size,
char: 1 byte;
short: 2 bytes,
int: 4 bytes,
float: 4 bytes,
double: 8 bytes.
This principle is used At the time, we follow the downward alignment method, that is, the total space occupied by the data declared first is an integer multiple of the following data type. Such as
typedef struct Test//首先考虑自身的对齐
{
char a; //1字节
short b; //2字节
int c; //4字节
long d; //8字节
}Test;
We can know that its type corresponds to 1/2/4/8 bytes, and this is far from the final result, but it is certain that the result must be greater than 15, so how to calculate it?
According to the principle of our basic data types, if the space above is an integer multiple of the space below, then
typedef struct Test//首先考虑自身的对齐
{
char a; //1字节+1字节
short b; //2字节 .....一共4字节
int c; //4字节 .....一共8字节
long d; //8字节 .....一共16字节
}Test;
So the answer is 16 bytes, but it is not applicable everywhere here. It needs to be used in conjunction with the third rule, which will be introduced later. Note
Rule two, the specified alignment value of the program
In addition to the default alignment of the data type, we can also customize the alignment size, that is, use #pragma pack(value) to specify the alignment value as value. In this way, we do not need to be an integer multiple of the next data type when calculating the space, but only need to be an integer multiple of the value (there are exceptions, combined with rule 4).
First look at the following code:
#pragma pack (2)
typedef struct ASS
{
char a; //1字节+1字节(与2对齐而不是与4对齐) .....一共2字节
int b; //4字节 .....一共6字节
double c; //8字节 .....一共14字节
char d; //1字节+1字节 .....一共16字节
}ASS;
So by comparing all the above alignments with 2, the result is 16 bytes
Rule 3: Self-alignment value of custom type
In addition to the basic alignment in the above two structures, often our calculated value still deviates from the final result, because we also need to consider the alignment of the structure itself. Also called the self-alignment value of a custom type, that is, the value with the largest self-alignment value among the members of a structure or class, which is an integer multiple of the maximum alignment of the data type in the structure,
for example:
typedef struct ASS
{
char a; //1字节
char b; //1字节+2字节 .....一共4字节
int c; //4字节 .....一共8字节
char d; //1字节 .....一共9字节
}ASS;
Its result is far from the simple calculation of electric shock 9, but the result of its space size is 12, because it is aligned with (int), so 3 bytes are added on the basis of 9.
Rule four, the effective alignment value of the custom type
Rule 4 is the core part of calculating the alignment space. After #pragma pack(value) customizes the alignment size, we need to find the effective value if we want to judge the real alignment size. Here we remember one point, take the two The smallest value in the aligner is aligned (once the occurrence of #pragma pack(value), all alignment judgments must consider the effective alignment value, including the self-alignment value of the custom type in Rule 3, which is the smallest of the two )
Such as the following procedure:
#pragma pack(2)
typedef struct ASS
{
char a; //1字节+1字节(在2与4中取2对齐) .....一共2字节
int b; //4字节 (在2与8中取2对齐) .....一共6字节
double c; //8字节 .....一共14字节
short d; //2字节 .....一共16字节
int f; //4字节 .......一共20字节(是2的倍数不用往8的倍数靠)
}ASS
So the result is 20, char and 2 are aligned, so 1 byte of space is added at the end, a total of 6 bytes with int is a multiple of 2, plus a total of 14 bytes of double below, which is a multiple of 2, plus The 2 bytes of short, a total of 16 bytes, and the 4 bytes of int added at the end, a total of 20 bytes. Here, our self-alignment value for the custom type is 8, but we take the smallest of 8 and 2. Therefore, 20 is a multiple of 2, and there is no need to make up. The result is 20.
Keep these four rules in mind when aligning bytes, and you can correctly calculate the required result by step-by-step execution.