1. Structure byte alignment
1.1 try
#include <stdio.h> struct S1{ char c1; char c2; int n; }; struct S2{ char c1; int n; char c2; }; struct S3{ int n; char c1; char c2; }; int main(){ printf("sizeof(struct S1) = %ld\n",sizeof(struct S1)); printf("sizeof(struct S2) = %ld\n",sizeof(struct S2)); printf("sizeof(struct S3) = %ld\n",sizeof(struct S3)); }
Output result:
sizeof(struct S1) = 8 sizeof(struct S2) = 12 sizeof(struct S3) = 8
In C language, the memory occupied by structures is continuous, but the addresses between members are not necessarily continuous. So there is "byte alignment".
1.2 default principle of byte alignment
The size of the structure variable must be an integer multiple of the size of its largest data type. If the size of a data type is not enough, fill in bytes.
The address of a structure variable must be the same as that of its first member.
1.3 practice
#include <stdio.h> struct Box{ int height; char a[10]; double width; char type; }; int main(void) { struct Box box; printf("box = %p\n", &box); printf("box.height = %p\n", &box.height); printf("box.a = %p\n", box.a); printf("box.width = %p\n", &box.width); printf("box.type = %p\n", &box.type); printf("box = %d\n", sizeof(box)); return 0; }
Output result:
box = 0x7ffee0738c10 box.height = 0x7ffee0738c10 box.a = 0x7ffee0738c14 box.width = 0x7ffee0738c20 box.type = 0x7ffee0738c28 box = 32
2. Four memory areas
2.1 testing
#include <stdio.h> #include <stdlib.h> void f1(){ int f1local1; int f1local2; static int f1static1; static int f1static2; int* f1dynamic1 = malloc(sizeof(int)); int* f1dynamic2 = malloc(sizeof(int)); printf("--------------f1()----------------\n"); printf("&f1local1 = %p\n",&f1local1); printf("&f1local2 = %p\n",&f1local2); printf("&f1static1 = %p\n",&f1static1); printf("&f1static2 = %p\n",&f1static2); printf("f1dynamic1 = %p\n",f1dynamic1); printf("f1dynamic2 = %p\n",f1dynamic2); printf("\"f1string1\" = %p\n","f1string1"); printf("\"f1string2\" = %p\n","f1string2"); printf("--------------f1()----------------\n"); free(f1dynamic1); free(f1dynamic2); } void f2(){ int f2local1; int f2local2; static int f2static1; static int f2static2; int* f2dynamic1 = malloc(sizeof(int)); int* f2dynamic2 = malloc(sizeof(int)); printf("--------------f2()----------------\n"); printf("&f2local1 = %p\n",&f2local1); printf("&f2local2 = %p\n",&f2local2); printf("&f2static1 = %p\n",&f2static1); printf("&f2static2 = %p\n",&f2static2); printf("f2dynamic1 = %p\n",f2dynamic1); printf("f2dynamic2 = %p\n",f2dynamic2); printf("\"f2string1\" = %p\n","f2string1"); printf("\"f2string2\" = %p\n","f2string2"); printf("--------------f2()----------------\n"); free(f2dynamic1); free(f2dynamic2); } int static1; int static2; int main(){ int local1; int local2; int* dynamic1 = malloc(sizeof(int)); int* dynamic2 = malloc(sizeof(int)); printf("&local1 = %p\n",&local1); printf("&local2 = %p\n",&local2); printf("&static1 = %p\n",&static1); printf("&static2 = %p\n",&static2); printf("dynamic1 = %p\n",dynamic1); printf("dynamic2 = %p\n",dynamic2); printf("\"string1\" = %p\n","string1"); printf("\"string2\" = %p\n","string2"); printf("&f1 = %p\n",&f1); printf("&f2 = %p\n",&f2); f1(); f2(); }
Execution result:
&local1 = 0x7fff5345832c &local2 = 0x7fff53458328 &static1 = 0x601050 &static2 = 0x601054 dynamic1 = 0x13dc2a0 dynamic2 = 0x13dc2c0 "string1" = 0x400bf7 "string2" = 0x400c0f &f1 = 0x400666 &f2 = 0x400761 --------------f1()---------------- &f1local1 = 0x7fff534582fc &f1local2 = 0x7fff534582f8 &f1static1 = 0x601040 &f1static2 = 0x601044 f1dynamic1 = 0x13dc6f0 f1dynamic2 = 0x13dc710 "f1string1" = 0x400a97 "f1string2" = 0x400ab3 --------------f1()---------------- --------------f2()---------------- &f2local1 = 0x7fff534582fc &f2local2 = 0x7fff534582f8 &f2static1 = 0x601048 &f2static2 = 0x60104c f2dynamic1 = 0x13dc710 f2dynamic2 = 0x13dc6f0 "f2string1" = 0x400b5f "f2string2" = 0x400b7b --------------f2()----------------
analysis:
(1) Local variables, static variables, dynamically allocated memory, string constants and functions are put together, even in different functions.
(2) The storage address size of variables has the following characteristics:
String constants and codes < static variables < dynamically allocated memory < local variables
(3) Static variables, dynamically allocated memory, string constants and adjacent variable addresses of functions are incremented. The addresses of local variables and adjacent variables are decremented.
(4) String constants are associated with functions.
The above description shows that the code is stored in different areas by type in memory.
2.2 stack
It is automatically allocated and released by the compiler. It mainly stores the values of function parameters and local variables.
2.3 heap
The programmer shall apply for allocation and release by himself. malloc(), calloc(), realloc() functions are required to apply for it, and free() function is used to release it. If it is not released, pointer dangling / wild pointer may appear.
The function cannot return a pointer to the stack area, but it can return a pointer to the heap area.
2.4 data area
Variables are marked with static keyword, which saves static variables.
1. Initialized global variables and initialized static variables are in one area;
2. Uninitialized global variables and uninitialized static variables are in a block area, which is called BSS(Block Started by Symbol);
3. The life cycle of static variables is the whole source program, and can only be initialized once. Subsequent initialization will be ignored.
(if not initialized, numerical data will be initialized to 0 by default, and character data will be initialized to NULL by default).
The array of the whole data area is uniformly destroyed by the system after the program is completed.
2.5 code area
Used to store compiled executable code, binary code and machine code.
3. The difference between heap and stack
No. | Comparative aspect | Stack | heap |
---|---|---|---|
1 | management style | It is automatically managed by the system and takes the execution function as the unit | Manually controlled by the programmer |
2 | Space size | Space size is determined at compile time (parameter + local variable) | It is global and has no size limit. |
3 | Distribution mode | Function execution, automatic allocation by the system; When the function ends, the system will automatically recycle it immediately. | Use new/malloc() to allocate the release manually; Manually release using delete/free() |
4 | advantage | Easy to use, do not need to care about memory application release. | Can be used across functions. |
5 | shortcoming | Can only be used inside functions. | Easy to cause memory leakage. |
4. Display target file section size: size command
Meaning of each section:
No. | section | name | meaning |
---|---|---|---|
1 | text | Code segment / text segment | The area of memory where program execution code is stored. The size of this area is determined before running and is usually read-only. Some variables, such as read-only constants, may contain constants. |
2 | data | Data segment | An area of memory that holds initialized global variables in a program. The data segment belongs to static memory allocation. |
3 | bss | BSS segment | An area of memory that holds uninitialized global variables in a program. BSS is the abbreviation of English Block Started by Symbol. The BSS segment is a static memory allocation. |
dec and hex are the sum of the first three regions, dec is decimal and Hex is hexadecimal.
Sections not shown:
No. | section | meaning |
---|---|---|
1 | stack | Store the local variables temporarily created by the program, that is, the variables defined in the function bracket {} (excluding the variables declared by static). When the function is called, the parameters will also be pushed into the process stack that initiated the call, and the return value of the function will also be stored back on the stack after the call. |
2 | heap | The memory segment dynamically allocated by the storage program is not fixed in size and can be dynamically expanded or reduced. When malloc() and other functions are called to allocate memory, the heap is expanded; When functions such as free() are called to free up memory, the heap is reduced. |