Structure byte alignment and common body size

Keywords: C++

1. Structure memory alignment

Structure memory alignment is often asked in written examination and interview, so to make a summary, first verify the memory size of different structures through code:

#include <stdio.h>
struct Node1{
    char c1;
    int val1;
    char c2;
};
struct Node2{
    char c1;
    char c2;
    int val1;
};
struct Node3{
    char c1;
    char array[10];
};
struct Node4{
    char val1;
    int arrar[10];
};
int main(){
    printf("Node1 size = %d\n",sizeof(struct Node1));
    printf("Node2 size = %d\n",sizeof(struct Node2));
    printf("Node3 size = %d\n",sizeof(struct Node3));
    printf("Node4 size = %d\n",sizeof(struct Node4));

    return 0;
}

The running result of the code is:

 

Through the above code running results, it can be found that Node1 and Node2 define the same number of variables, but the size of Node1 is 12 and the size of Node2 is 8. Why?

Here, first clarify two concepts: alignment number and maximum alignment number. In the structure, alignment number is the size of each member type. For example, in Node1, alignment number is {1,4,1}. In array, alignment number is not the size of array, but the size of array members. Therefore, the alignment number of Node3 is {1,1}, and the alignment number of Node4 is {1,4}. The maximum alignment number is the maximum of the alignment numbers (gcc compiler). The maximum alignment number may be affected by the compiler. Usually, the compiler will have the compiler alignment number. The maximum alignment number should be the smaller of the compiler alignment number and the maximum alignment number of the structure. For example, the VS compiler alignment number is 8. If the maximum alignment number of the structure is 16, Then the maximum alignment number of the calculated structure should be 8. My compiler is GCC, so the maximum number of alignments is the maximum number of structure alignments.

After you know the maximum alignment number, you can calculate the size of the structure. You need to make it clear that the size of the structure must be an integer multiple of the maximum alignment number. The member types of Node1 and Node2 are the same. Why is the size of Node1 12 bytes and Node2 8 bytes. This is because of the continuity of the structure memory. When the storage capacity is less than the memory size of the maximum alignment number, as long as the member can be saved, the structure will save the member variable in the memory space of the maximum alignment tree. This avoids excessive waste of memory. Therefore, the memory size of the above structures is calculated as follows:

sizeof (Node1) = 1 + 3 (waste) + 4 + 1 + 3 (waste) = 12

sizeof (Node2) = 1 + 1 + 2 (waste) + 4 = 8

sizeof(Node3) = 1 + 1 * 10 = 11

sizeof (Node4) = 1 + 3 (waste) + 4 * 10 = 44  

So how should the size of nested structures be calculated? Take the following examples:

#include <stdio.h>
struct Node1{
    char c1;
    int val1;
    char c2;
};
struct Node2{
    char c1;
    struct Node1 node;
    double val1;
};

int main(){
    printf("Node1 size = %d\n",sizeof(struct Node1));
    printf("Node2 size = %d\n",sizeof(struct Node2));
    return 0;
}

The result of code running is:

 

  It can be made clear that the alignment number of nested structures is the maximum alignment number of nested structures, so the alignment number of Node1 is {1,4,1}, the alignment number of Node2 is {1,4,8}, and the maximum alignment numbers are 4 and 8 respectively. The size calculation method of the two structures in the code is as follows:

sizeof (Node1) = 1 + 3 (waste) + 4 + 1 + 3 (waste) = 12

sizeof (Node2) = 1 + 7 (waste) + 12 + 4 (waste) + 8 = 24

2. Memory size of the community

For the following community, the code to read its size is as follows:

#include <stdio.h>

union un1{
    int val;
    char c;
    double d;
};
union un2{
    int val;
    char array[5];
};

int main(){
    printf("un1 size = %d\n",sizeof(union un1));
    printf("un2 size = %d\n",sizeof(union un2));
    return 0;
}

The running result of the code is:

 

  The reason why a common body is called a common body is that its member variables share memory. Since the shared memory is shared, the memory space occupied by the common body must be able to store the member type with the largest memory. The maximum memory member of un1 is double and the size is 8 bytes. Therefore, the size of un1 is 8 bytes. Why is the memory size of un2 not 5? This is because to align the memory, the common body also follows the memory alignment principle. The maximum alignment number of un2 is 4, so the size of un2 should be an integer multiple of 4. Therefore, sizeof (un2) = 8

3. Size of enumeration

Incidentally, the enumerated memory size is mentioned. The code verification is as follows:

#include <stdio.h>

enum Colour {
    RED,
    GREEN,
    BLUE
};
enum ProgramLanguage {
    python = 0xffffffffff,
    c = 8,
    java
};

int main()
{
    printf("Colour size = %d\n",sizeof(enum Colour));
    printf("ProgramLanguage size = %d\n",sizeof(enum ProgramLanguage));
    return 0;
}

The running result of the code is:

 

  It can be seen that the size of enumeration type is given by the compiler according to the defined value. In actual use, it rarely exceeds the size of 4 bytes.

Posted by scheibyem on Fri, 29 Oct 2021 10:30:18 -0700