Hurry up! Structure memory alignment (calculate structure size) Full of dry goods!

Structure memory alignment rules

We know that integer variables have their own size, floating-point variables have their own size, and arrays also have their own size, so does the structure have its own size?
The answer is yes, the structure also has its own size, but the size of the structure cannot be obtained simply by adding the size of each structure member .

The size calculation of the structure follows the alignment rules of the structure :

1> The first member is at the address with offset 0 from the structure variable. (That is, the first address of the structure, that is, aligned to 0)
2>Other member variables must be aligned to an address that is an integer multiple of a certain number (alignment number).
3> The total size of the structure is an integer multiple of the maximum alignment (each member variable has an alignment).
4> If a structure is nested, the nested structure is aligned to an integer multiple of its own maximum alignment, and the overall size of the structure is an integer multiple of all maximum alignments (including the alignment of the nested structure).

Alignment = the smaller value between the size of the structure member variable itself and the default alignment of the compiler.
Note: The default alignment number in VS is 8. Not all compilers have a default alignment number. When the compiler does not have a default alignment number, the size of the member variable is the alignment number of the member.

Struct Size Calculation

Knowing the structure memory alignment rules, we can calculate the size of the structure. Computing the size of a structure can be divided into three steps . Let's take the following structure as an example:

struct S
{
    
    
	double d;
	char c;
	int i;
};

Step 1: Find out the size of each member variable and compare it with the default alignment number of the compiler, and take the smaller value as the alignment number of the member variable.

insert image description here
Note: I am using the VS compiler, so the default alignment is 8.

Step 2: Draw their relative positions in memory according to their corresponding alignment numbers.

insert image description here
Step 3: Determine the size of the final structure through the maximum alignment number.

We can know from the figure that the green part (occupied by double d members) + the red part (occupied by char c members) + the purple part (occupied by int i members) + the white part between red and purple (wasted) occupies a total of 16 bytes of memory space.

We need to compare the total memory space occupied by them (16) with the maximum alignment number of structure members (8). The total size of the structure is an integer multiple of the maximum alignment number . At this time, 16 is exactly an integer multiple of 8, so The size of the structure under the VS compiler is 16 bytes. That is to create a structure variable of this type, and the memory needs to open up 16 bytes of memory space for it.

Note: In most cases, the total number of bytes occupied by a member variable is not necessarily an integer multiple of the maximum alignment number in its member variable. In this case, we need to expand it to an integer multiple of the maximum alignment number.

Why does memory alignment exist?

Platform reasons (porting reasons ): Not all hardware platforms can access any data at any address; some platforms can only obtain certain types of data at certain addresses, otherwise a hardware exception will be thrown.
For example, when a platform wants to fetch an integer data, it can only be obtained at a location whose address is a multiple of 4, then memory alignment is required at this time, otherwise the integer data cannot be accessed.

Performance reasons : Data structures (especially stacks) should be aligned on natural boundaries as much as possible. The reason is that to access unaligned memory, the processor needs to make two memory accesses; aligned memory accesses only need one.

In fact, the memory alignment of the structure is the practice of exchanging space for time.

Tips for Designing Structures

In fact, when we design the structure, if the order of the structure members is designed reasonably, unnecessary memory consumption can be avoided.

The member variables of the two structures are the same, but the order of the member variables is different, and the size of the structures may be different:

struct S1
{
    
    
	char a;
	char b;
	int c;
};//结构体1
struct S2
{
    
    
	char a;
	int c;
	char b;
};//结构体2

We can see that the member variables of structure 1 and structure 2 are exactly the same, but when we calculate the size of the two structures according to the memory alignment rules, we will find that the sizes of the two structures are different. In the VS compiler The first structure below has a size of 8, and the second structure has a size of 12.

It can be seen that the order of structure member variables is different, which may cause unnecessary loss of memory. Gathering members that occupy a small space together can effectively avoid unnecessary waste of memory.

How to modify the default alignment number?

To modify the compiler's default alignment, we need to resort to the following preprocessing commands:

#pragma pack()

If you fill in the numbers in the brackets of the preprocessing command, the default alignment will be changed to the corresponding number; if you only use the preprocessing command and do not fill in the numbers in the brackets, then it will return to the default alignment of the compiler.

#include <stdio.h>

#pragma pack(4)//设置默认对齐数为4
struct S1
{
    
    
	char a;//1/4->1
	int b;//4/4->4
	char c;//1/4->1
};//12
#pragma pack()//取消设置的默认对齐数,还原为默认

#pragma pack(1)//设置默认对齐数为1
struct S2
{
    
    
	char a;//1/1->1
	int b;//4/1->1
	char c;//1/1->1
};//6
#pragma pack()//取消设置的默认对齐数,还原为默认

int main()
{
    
    
	printf("%d\n", sizeof(struct S1));//打印结果为12
	printf("%d\n", sizeof(struct S2));//打印结果为6
	return 0;
}

Therefore, when the alignment of the structure is not appropriate, we can change the default alignment by ourselves.

Guess you like

Origin blog.csdn.net/weixin_62976968/article/details/131332664