Byte alignment method

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.

Guess you like

Origin blog.csdn.net/dream_i_success/article/details/110247818