Alignment rules for structures in memory

 After a structure variable is defined, its storage in memory is not equal to the sum of the widths of the elements it contains.

Example 1:

                                      #include <iostream>

                                      using namespace std;

                                         struct X

                                         {

                                              char a;

                                              int b;

                                              double c;

                                         }S1;

                                     void main()

                                    {

                                         cout << sizeof(S1) << endl;

                                         cout << sizeof(S1.a) << endl;

                                         cout << sizeof(S1.b) << endl;

                                         cout << sizeof(S1.c) << endl;

                                    }

     For example, after the structure variable S1 in Example 1 is defined, after testing, it will be found that sizeof(S1) = 16, and its value is not equal to sizeof(S1.a) = 1, sizeof(S1.b) = 4 and sizeof(S1. c) = the sum of the three, there is a storage alignment problem.

    Principle 1: The elements in the structure are placed in the memory one by one in the order of definition, but they are not arranged closely. Starting from the first address stored in the structure, when each element is placed in the memory, it will think that the memory is divided according to its own size, so the position where the element is placed must start at an integer multiple of its own width (based on the structure The first address of the body variable is calculated as 0).

    For example, in this example, first the system will store the character variable a in the 0th byte (relative address, which refers to the first address of memory allocation); then when storing the integer variable b, it will be stored in units of 4 bytes. Since the first four-byte module already has data, it will be stored in the second four-byte module, that is, it will be stored in 4~8 bytes; similarly, when storing the double-precision real variable c, due to its The width is 8, and it will be stored in units of 8 bytes, that is, it will find the first empty position that is an integer multiple of 8 and start storing it. In this example, because the first 8 characters section module is already occupied, so c is stored in the second 8-byte module. The overall storage diagram is shown in Figure 1.

    Consider another example.

Example 2:

                                           struct X

                                           {

                                                char a;

                                                double b;

                                                int c;

                                            }S2;

    In the second example, the positions of the double-type variable and the int-type variable are simply exchanged. The test program remains unchanged, but the test results are completely different. sizeof(S2)=24 is different from the 8+8+4=20 we calculated according to the first principle. This leads to our second principle.

   

 

    Principle 2: After first-principle analysis, check whether the calculated storage unit is an integer multiple of the length of the widest element among all elements. If yes, end; if not, fill in an integer multiple of it.

    In Example 2, the storage length after our analysis is 20 bytes, which is not an integer multiple of the widest element length of 8, so it is padded to an integer multiple of 8, which is 24. That way there's no problem. Its storage diagram is shown in Figure 2.

    Once you master these two principles, you can analyze all data storage alignment issues. Let’s look at a few more examples and apply the above two principles to judge.

Example three:

                                              struct X

                                              { 

                                                   double a;

                                                   char b;

                                                   int c;     

                                              }S3;

    First, let’s analyze it based on principle one. According to the defined order, the double type a is stored first, stored in the 0th to 7th bytes; followed by the char type b, stored in the 8th byte; followed by the int type c, after the order check, it is found that the previous Three four-byte modules are all occupied, so they are stored in the fourth four-byte module, which is the 12th to 15th bytes. According to the first principle analysis, 16 bytes are obtained. 16 is exactly an integer multiple of the width 8 of the widest element a, so the storage space occupied by the structure variable S3 is 16 bytes. The storage structure is shown in Figure 3.

Example 4:

                                              struct X

                                              { 

                                                   double a;

                                                   char b;

                                                   int c;

                                                   char d;   

                                              }S4;

    Still first analyze according to the first principle, the number of bytes obtained is 8+4+4+1=17; then complete according to the second principle, then the storage space occupied by the structure variable S4 is 24. The storage structure is shown in Figure 4:

Example five:

                                              struct X

                                              { 

                                                   double a;

                                                   char b;

                                                   int c;

                                                   char d;

                                                   int e; 

                                               }S5;

    Also combined with the analysis of Principle 1 and Principle 2, it can be seen that after adding an int type variable at the end of the internal variable definition of the structure based on S4, the space occupied by the structure has not increased and is still 24. The schematic diagram of the storage structure is shown in Figure 5.

Example 6:

    If the variable e added in Example 5 is placed in the first defined position, the situation will be different. The storage space occupied by the structure will become 32. The schematic diagram of its storage structure is shown in Figure 6.

                                              struct X

                                              { 

                                                  int e;

                                                  double a;

                                                  char b;

                                                  int c;

                                                  char d;

                                              }S6;

    Supplement: The previous introductions are all structures whose elements are basic data types. So what about when they contain pointers, arrays, or other structure variables or union variables?

    1. Contains pointer types. Just remember that the storage space occupied by the pointer itself is 4 bytes, regardless of what type of pointer it points to.

Example 7:

                    struct X              struct Y               struct Z

                    {                     {                      {     

                       char *a;              int *b;                 double *c;

                    };                     };                     };

    After testing, it can be seen that the values ​​of sizeof(X), sizeof(Y) and sizeof(Z) are all 4.

    2. Contains constructed data types (arrays, structures and unions). The first thing to make clear is that when calculating the storage space, the structure must be regarded as a whole to open up storage space for it; the second thing to make clear is that the final filling is based on the longest width of the basic data type elements among all elements. It means that although the structure should be regarded as a whole, it will not be filled according to the length of the storage space occupied by the contained structure (even if it may be the longest).

Example 8:

                                      struct X

                                     {

                                          char a;

                                          int b;

                                          double c;

                                      };

                                      struct Y

                                      {

                                           char a;

                                           X b;

                                       };

    After testing, it can be seen that sizeof(X) is 16 and sizeof(Y) is 24. That is, when calculating the storage length of Y, the initial position when storing the second element b is an integer multiple of the double length 8, not an integer multiple of 16. That is, the storage space allocated by the system for b is the 8~23 bytes.

    If the two elements of Y, a of type char and b of type There are 17 bytes in total, which is not an integer multiple of the width 8 of the longest basic type double, so it needs to be filled to an integer multiple of 8, that is, 24. After testing, the value of sizeof(Y) is 24.

    Since the space occupied by a structure is related to the type of its internal elements and the arrangement of different types of elements, when defining a structure, after the element types and quantities are determined, we should also pay attention to the definition order of its internal elements.

Guess you like

Origin blog.csdn.net/m0_52467164/article/details/120293187