Data structure type (memory articles)

Data structure type (memory chapter) super-full structure, union, enumeration memory interpretation (applicable to C language entry)

1. The memory of the structure

Memory alignment

rule:

1. The address where the first data member of the structure is stored is the address where the offset of the structure variable is 0.

2. The other starting address is an integer multiple of the memory occupied by this type of variable. If the insufficient part is filled with data to an integer multiple of the memory occupied

3. The total memory occupied by the structure is an integer multiple of the maximum number of bytes of the basic data type in the members of the structure

(See Diagram 1-1)

#include<stdio.h>

struct str1 {
    
       // ??
	char a;     //  1 byte  //此处若删除char a 则所占内存为 24 以验证规则 1;(自行验证)
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
	char ch;    //  1 byte
}s1;            // 32 byte

//将结构体内部变量调换位置后结构体内存占用发生改变

struct str2 {
    
       // ?? 
	char a;     //  1 byte
	char ch;    //  1 byte
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
}s2;            // 24 byte

int main() {
    
    
	printf("%d\n",sizeof(s1));  //输出结果:32
	printf("%d\n",sizeof(s2));  //输出结果:24
	return 0;
}
Graphic 1-1

Insert picture description here

If the structure contains an array: (see Figure 1-2)

#include<stdio.h>

// 当结构体成员包含数组:
struct str3 {
    
    
	int a;       //  4 byte
	double b;    //  8 byte(最大)  
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s3;             //  结果:32

struct str4 {
    
    
	double b;    //  8 byte(最大)
	int a;       //  4 byte
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s4;             //  结果:24

int main() {
    
    
	//如果结构体成员含有数组:
	printf("%d\n", sizeof(s3));  //输出结果:32
	printf("%d\n", sizeof(s4));  //输出结果:24
	return 0;
}
Illustration 1-2

Insert picture description here

If the structure contains a structure:

#include<stdio.h>

struct str5 {
    
    
	char ch;
	short sh;
	int num;
}s5;

struct str6 {
    
    
	int n;
	struct str5 s5;
}s6;

struct str7 {
    
    
	int n;
	char ch;
	short sh;
	int num;
}s7;

int main() {
    
    
	//如果结构体成员包含结构体:
	printf("%d\n", sizeof(s5));  //输出结果:8
	printf("%d\n", sizeof(s6));  //输出结果:12 --> sizeof(int)+8
	printf("%d\n", sizeof(s7));  //输出结果:12
	return 0;
}

Conclusion: The structure str6 and str7 are equivalent. When the members of the structure contain the structure, it is equivalent to expand the content of the member structure

Note: The structure contained in a structure member cannot be itself!

[The complete code is as follows]
#include<stdio.h>

struct str1 {
    
       //  内部求和为 18byte
	char a;     //  1 byte
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
	char ch;    //  1 byte
}s1;            //  结果:32 byte

// 将结构体成员变量调换位置后结构体内存占用发生改变:
struct str2 {
    
       //  内部求和为 18byte
	char a;     //  1 byte
	char ch;    //  1 byte
	int b;      //  4 byte
	float c;    //  4 byte
	double d;   //  8 byte(最大)
}s2;            //  结果:24 byte

// 当结构体成员包含数组:
struct str3 {
    
    
	int a;       //  4 byte
	double b;    //  8 byte(最大)  
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s3;             //  结果:32

struct str4 {
    
    
	double b;    //  8 byte(最大)
	int a;       //  4 byte
	char arr[9]; //  9 byte(char基本数据类型占 1byte)
}s4;             //  结果:24

// 当结构体成员包含结构体:
struct str5 {
    
    
	char ch;
	short sh;
	int num;
}s5;

struct str6 {
    
    
	int n;
	struct str5 s5;
}s6;

struct str7 {
    
    
	int n;
	char ch;
	short sh;
	int num;
}s7;

int main() {
    
    

	printf("%d\n",sizeof(s1));  //输出结果:32
	printf("%d\n",sizeof(s2));  //输出结果:24
	printf("\n");
	//如果结构体成员含有数组:
	printf("%d\n", sizeof(s3));  //输出结果:32
	printf("%d\n", sizeof(s4));  //输出结果:24
	printf("\n");
	//如果结构体成员包含结构体:
	printf("%d\n", sizeof(s5));  //输出结果:8
	printf("%d\n", sizeof(s6));  //输出结果:12
	printf("%d\n", sizeof(s7));  //输出结果:12
	return 0;
}

2. Consortium's memory

rule:

1. The size must be large enough to accommodate the widest member
2. The size can be divisible by the size of all the basic data types it contains

#include<stdio.h>

union MyUnion1{
    
    
	char s[9];     //  9 byte (char类型为 1 byte)
	int n;         //  4 byte
	double d;      //  8 byte
};                 // 16 byte

union MyUnion2 {
    
    
	char s[5];     //  5 byte
	int n;         //  4 byte
	double d;      //  8 byte
};                 //  8 byte
int main() {
    
    
	printf("%d\n", sizeof(MyUnion1));     // 结果:16
	printf("%d\n", sizeof(MyUnion2));     // 结果:8
}

3. Enumerated memory

#include<stdio.h>

enum Enum {
    
    
	Enum1,      // (int) 4 byte
	Enum2,      // (int) 4 byte
	Enum3       // (int) 4 byte
}MyEnum;

int main() {
    
    
	printf("%d\n", sizeof(MyEnum));  // 结果:4
	printf("%d\n", sizeof(Enum1));   // 结果:4
	printf("%d\n", sizeof(Enum2));   // 结果:4
	printf("%d\n", sizeof(Enum3));   // 结果:4
	return 0;
}

Most of the explanations about enumeration are: enumeration is 4 bytes; (example: the above situation)

——The problem of enumerating memory does not need to be too deep, but I want to explore it.

The standard C language description does not clearly specify the size of the space occupied by the enumeration type, which means: "The size of the enumeration type is the size of the integer that can accommodate the largest enumeration sub-value." At the same time, the standard also states: "In the enumeration type the value of the sub-enumeration must be able to use an int expression. "

#include<stdio.h>

enum Enum {
    
    
	Enum1 = 0x7f7f7f7f7f,    // (int类型最大值) (int) 4 byte
	Enum2,                   //               (int) 4 byte
	Enum3,                   //               (int) 4 byte
	Enum4 = 5,
	Enum5,
    Enum6 = 0x7f7f7f7f7f,    //(int类型最大值)
	Enum7
}MyEnum;

int main() {
    
    
	printf("%d\n", sizeof(MyEnum));  // 结果:8
	printf("%d\n", sizeof(Enum1));   // 结果:8
	printf("%d\n", sizeof(Enum2));   // 结果:8
	printf("%d\n", sizeof(Enum4));   // 结果:4
    printf("%d\n", sizeof(Enum5));   // 结果:4
    printf("%d\n", sizeof(Enum6));   // 结果:8
    printf("%d\n", sizeof(Enum7));   // 结果:8
	return 0;
}

When the enumeration sub-value exceeds the int range, the enumeration byte occupies 8 byte

I thought it was an enumeration defined as a long type size, but found that the output of the sub-value is not the correct value output, and it still overflows;

This may be related to the size of the int type:

(About the int type) Its size is the word length of the computer, which is related to the number of cpu registers

General situation: 32-bit computer is 4 bytes, 64-bit computer is 8 bytes

However, most of the debugging results in the x64 computer environment are still 4 bytes, which may be related to various conditions such as the compiler.

Such an article was found in the search data: https://blog.csdn.net/HES_C/article/details/88668276

According to the description of c language, it can be achieved, but I failed to achieve it. Some other reasonable explanations were obtained from the query:

The details are as follows:

1. Reprint: https://embedded.fm/blog/2016/6/28/how-big-is-an-enum

2. Message from Zhihu:

Insert picture description here

Enum itself is not stored in memory as a variable, but the enum itself is used as a variable (including specifying which enumeration value is), because this variable contains a part of the value in the enumeration type, so space will be allocated. This specific The size of the value should be related to the specified value of the machine and enumeration value.

Guess you like

Origin blog.csdn.net/zhuiyizhifengfu/article/details/113063937