❤️ Graphic C language, structure alignment, nanny level teaching, suggestions collection ❤️

Keywords: C C++

catalogue

1, Alignment rules for structures

2, Acquiescence

3, Example explanation

1. Example 1

  2. Example 2

  3. Example 3

  4. Example 4

4, Why is there memory alignment?

5, Modify the default number of alignments

  6, Summary

1, Alignment rules for structures

1. The first member of the structure is always placed at the address with the starting position offset of 0

2. The structure from the second member is always placed in an integer multiple of an aligned number
   Alignment number = the compiler's default alignment number and the smaller value of the variable's own size

3. The total size of the. Structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).

4. If a structure is nested, the nested structure is aligned to an integer multiple of its maximum alignment number, and the overall size of the structure is an integer multiple of all the maximum alignment numbers (including the alignment number of nested structures).

2, Acquiescence

Linux does not have a default alignment number

The default alignment number of Vs is 8

3, Example explanation

1. Example 1

int main()
{
	struct S1
	{
		char c1;
		int i;
		char c2;
	};
	printf("%d\n", sizeof(struct S1));
	return 0;
}

  c1 is an address with an offset of 0 at the starting position of the structure.

i is the second member. It is always placed in an integer multiple of an alignment number. Alignment number = the smaller value of the compiler's default alignment number and the size of the variable itself. i itself is 4 and Vs is 8 by default. We choose to start from 4 and discard all in the middle.

c2 itself is a byte, which is still 1 compared with Vs8.

According to the third rule, the total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).

The maximum alignment digit is 4. At this time, our memory is 8, and the total size is 9. Continue to extend to 11, and the total size is 12, which is an integer multiple of 4, in line with the third rule.

int main()
{
	struct S1
	{
		char c1;  //Byte size 1 Vs is 8, so it is 1
		int i;    //Byte size 4 Vs is 8, so it is 4
		char c2;  //Byte size 1 Vs is 8, so it is 1
	};
	printf("%d\n", sizeof(struct S1));
	return 0;
}

  2. Example 2

int main()
{
	struct S2
	{
		char c1;
		char c2;
		int i;
	};
	printf("%d\n", sizeof(struct S2));
	return 0;
}

 

c1 is an address with an offset of 0 at the starting position of the structure.

c2 is the second member. It is always placed in an integer multiple of an alignment number. Alignment number = the compiler's default alignment number and the smaller value of the variable's own size. c2 itself is 1 and Vs is 8 by default. We choose to start from 1.

i itself is 4 bytes, which is still 4 compared with Vs8.

According to the third rule, the total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).

The maximum alignment digit is 4. At this time, our memory is 7 and the total size is 8, which is an integer multiple of 4, in line with the third rule.

int main()
{
	struct S2
	{
		char c1;  //Byte size 1 Vs is 8, so it is 1
		char c2;  //Byte size 1 Vs is 8, so it is 1
		int i;    //Byte size 4 Vs is 8, so it is 4
	};
	printf("%d\n", sizeof(struct S2));
	return 0;
}

  3. Example 3

int main()
{
	struct S3
	{
		double d;
		char c;
		int i;
	};
	printf("%d\n", sizeof(struct S3));
	return 0;
}

  d address offset to 0 at the starting position of the structure.

c is the second member. It is always placed in an integer multiple of an alignment number. Alignment number = the compiler's default alignment number and the smaller value of the variable's own size. c2 itself is 1, Vs is 8 by default. We choose to start from 8.

i itself is 4 bytes, which is still 4 compared with Vs8. But it must start from 12, because the memory is 9 at this time, which should comply with the second rule.

According to the third rule, the total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).

The maximum alignment digit is 4. At this time, our memory is 15, and the total size is 16, which is an integer multiple of 8, in line with the third rule.

int main()
{
	struct S3
	{
		double d;   ///Byte size 8 Vs is 8, so it is 8
		char c;     //Byte size 1 Vs is 8, so it is 1
		int i;      //Byte size 4 Vs is 8, so it is 4
	};
	printf("%d\n", sizeof(struct S3));
	return 0;
}

  4. Example 4

int main()
{
	struct S3
	{  
		double d;     
		char c;        
		int i;         
	};
	printf("%d\n", sizeof(struct S3));
	struct S4
	{
		char c1;       //
		struct S3 s3;
		double d;
	};
	printf("%d\n", sizeof(struct S4));
	return 0;
}

  c1 is an address with an offset of 0 at the starting position of the structure.

According to the fourth rule, the nested structure is aligned to the integer multiple of its maximum alignment number, and the maximum integer multiple of S3 is 8. Therefore, we must start from 8 and discard it in the middle. The structure S3 itself is 16 and extend backward from 16 to 23

d is 8 bytes, complying with the rule from 24

According to the third rule, the total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).

The maximum alignment digit is 16. At this time, our memory is 23 and the total size is 24. Continue to extend to 32. The total size is 32, which is an integer multiple of 16, in line with the third rule.

int main()
{
	struct S3
	{  
		double d;      //Byte size 8 Vs is 8, so it is 8
		char c;        //Byte size 1 Vs is 8, so it is 1
		int i;         //Byte size 4 Vs is 8, so it is 4
	};
	printf("%d\n", sizeof(struct S3));
	struct S4
	{
		char c1;       //Byte size 1 Vs is 8, so it is 1
		struct S3 s3;  //Byte size 16 
		double d;      //Byte size 8 Vs is 8, so it is 8
	};
	printf("%d\n", sizeof(struct S4));
	return 0;
}

4, Why is there memory alignment?

Most references say this:

1. Platform reason (migration reason): not all hardware platforms can access any data at any address; Some hardware platforms can only get certain types of data at certain addresses, otherwise hardware exceptions will be thrown.

2. Performance reason: data structures (especially stacks) should be aligned on natural boundaries as much as possible. The reason is that in order to access misaligned memory, the processor needs to make two memory accesses; Aligned memory access requires only one access. Generally speaking, the memory alignment of structures is the practice of trading space for time.

When designing the structure, we should not only meet the alignment, but also save space. How to do this:

Let the members with small space gather together as much as possible.

struct S1
{
 char c1;
 int i;
 char c2;
};
struct S2
{
 char c1;
 char c2;
 int i;
};

S1 is as like as two peas of S2 type, but the size of S1 and S2 occupies some difference.

5, Modify the default number of alignments

#include <stdio.h>
#pragma pack(8) / / set the default alignment number to 8
struct S1
{
    char c1;
    int i;
    char c2;
};
#pragma pack() / / unset the default alignment number and restore it to the default
#pragma pack(1) / / set the default alignment number to 8
struct S2
{
    char c1;
    int i;
    char c2;
};
#pragma pack() / / unset the default alignment number and restore it to the default
int main()
{
    //What is the output?
    printf("%d\n", sizeof(struct S1));
    printf("%d\n", sizeof(struct S2));
    return 0;
}

  6, Summary

Now that I see here, please praise, comment and collect. Your three companies are the biggest driving force for my progress. Pay attention to me and learn and progress together

Posted by basim on Mon, 20 Sep 2021 22:30:56 -0700