Structure analysis of C language

Structure declaration

1. Basic knowledge of structure

A structure is a collection of values called member variables. Each member of a structure can be a variable of a different type.

struct tag //Structure label{ 
    member-list //Variable definition
} variable-list ;//Structural variable

2. Types of structural members

The members of a structure can be scalars, arrays, pointers, or even other structures.

Definition and initialization of structure variable

struct Point{
	int x;
	int y;
}p1; //Define variable p1 while declaring type

//Initialization: define variables and assign initial values at the same time.
struct Point p3 = {x, y};

Structure memory alignment

First, master the alignment rules of the structure:

  1. The first member is at the address offset 0 from the struct variable.
  2. Other member variables are to be aligned to an address that is an integral multiple of a number (alignment number).
    Alignment number = the smaller of the compiler's default alignment number and the member size. The default value in VS is 8 the default value in Linux is 4
  3. The total size of the structure is an integer multiple of the maximum number of alignments (one for each member variable).
  4. If a nested 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).

Structure memory alignment exercise:

struct S1
	char c1; //There are three sum = 1 and rem = 3 in a byte of 4;
	int i;  //Four bytes, three more are not enough, sum = 4 + 4, rem = 0;
	char c2; //One byte, sum = 9, rem = 0; other member variables should be aligned to the address 3 * 4 = 12, sum = 12 of an integer multiple of a number (alignment number);
printf("%d\n", sizeof(struct S1)); // 12

struct S2
	char c1; //There are three sum = 1 and rem = 3 in a byte of 4;
	char c2; //One byte three bytes and two sum = 1 + 1, rem = 2;
	int i; //Two of the four bytes are not enough, sum = 4 + 4, rem = 0; other member variables should be aligned to the address of an integer multiple of a number (alignment number), 2 * 4 = 8, sum = 8;
printf("%d\n", sizeof(struct S2)); // 8

struct S3
	double d; //Eight bytes sum = 8, rem = 0;
	char c;  //One byte sum = 8 + 1, rem = 3;
	int i;  //Four bytes are not enough, sum = 8 + 4 + 4, rem = 0;
printf("%d\n", sizeof(struct S3)); //The total size of the structure is an integer multiple of the maximum number of alignments (one for each member variable). 2 * 8, 16

struct S4
	char l; // One byte sum = 1, rem = 3;
	struct S3 S3; //Sixteen bytes sum = 4 + 16, rem = 0;
	double d; // Eight bytes sum = 20 + 8, rem = 0;
printf("%d\n", sizeof(struct S4)); //The overall size of a structure is an integral multiple of all the maximum alignments (including those of nested structures). 16 * 2, 32

Why does memory alignment exist?
1. Platform reason (migration reason): not all hardware platforms can access any data on any address; some hardware platforms can only get some specific types of data at some addresses, otherwise, hardware exceptions will be thrown.
2. Performance reasons: data structures (especially stacks) should be aligned on natural boundaries as much as possible. The reason is that in order to access the unaligned memory, the processor needs to make two memory accesses, while the aligned memory access only needs one access.
3. Memory alignment of the structure is a way to trade space for time.

Structural parameter transfer

struct S
	int data[1000];
	int num;

struct S s = { { 1, 2, 3, 4 }, 1000 };
//Structural parameter transfer
void print1(struct S s)
	printf("%d\n", s.num);
//Structure address parameters
void print2(struct S* ps)
	printf("%d\n", ps->num);

int main()
	print1(s); //Transfer structure
	print2(&s); // Forwarding address
	return 0;

Conclusion: when the function passes parameters, the parameters need to be stacked. If you pass a struct object, the struct is too large. The system overhead of parameter stack is large, so it will lead to performance degradation. When a structure transmits parameters, the address of the structure is to be transmitted.

Bit segment

The declaration and structure of a bit segment are similar, with two differences:
1. The members of the bit segment must be int, unsigned int, and signed int.
2. The member name of the segment is followed by a colon and a number.
For example:

struct A
	int _a:2;
	int _b:5;
	int _c:10;
	int _d:30;

A is a bit segment. What is the size of a? Eight

printf("%d\n",sizeof(struct A));//int type has four bytes, a total of 32 bits, so the first three are put into the first block of space when storing. Because the fourth one is 30 bits, the next fast space storage is opened, that is, two fast spaces are opened, that is, good 8 bytes. Other types can be obtained in the same way.

Memory allocation of bit segments
1. The members of a bit segment can be int, unsigned int, signed int, and char (belonging to the plastic family).
2. The space of bit segment is opened in the way of 4 bytes or 1 byte as required.
3. Bit segment involves many uncertain factors. Bit segment is not cross platform. It should be avoided in portable programs.

Cross platform problem of bit segment
1. Whether the int bit segment is treated as a signed number or an unsigned number is uncertain.
2. The maximum number of bit segments is uncertain. (16 bit machine max. 16, 32-bit machine max. 32, written as 27, there will be problems in 16 bit machine)
3. Whether the members in the bit segment are allocated from right to left or from right to left in memory has not been defined.
4. When a structure contains two bitsegments and the second bitsegment member is compared and cannot accommodate the remaining bits of the first bitsegment, it is uncertain whether to discard the remaining bits or use them.

Published 18 original articles, won praise 17, visited 1237
Private letter follow

Tags: Linux

Posted on Tue, 17 Mar 2020 00:00:18 -0700 by samyl