1 memory partition model
During the execution of C + + program, the general direction of memory is divided into four areas
- Code area: it stores the binary code of the function body and is managed by the operating system
- Global area: stores global variables, static variables and constants
- Stack area: automatically allocated and released by the compiler to store function parameter values, local variables, etc
- Heap area: it is allocated and released by the programmer. If the programmer does not release it, it will be recycled by the operating system at the end of the program
The meaning of four memory areas: the data stored in different areas give us different life cycles and give us greater flexibility in programming
1.1 before program operation
After the program is compiled, an exe executable program is generated. Before the program is executed, it is divided into two areas.
- Code area:
Store machine instructions executed by CPU
The code area is shared. The purpose of sharing is to have only one code in memory for frequently executed programs
The code area is read-only because it prevents the program from accidentally modifying its instructions - Global area:
Global and static variables. Constants are stored here
The constant area contains string constants and const decorated global constants
The data in this area is released by the operating system at the end of the program
eg:
//global variable int g_a = 10; int g_b = 10; //Global constant const int c_g_a = 10; const int c_g_b = 10; int main() { //local variable int a = 10; int b = 10; //Print address cout << "local variable a The address is: " << (int)&a << endl; cout << "local variable b The address is: " << (int)&b << endl; cout << "global variable g_a The address is: " << (int)&g_a << endl; cout << "global variable g_b The address is: " << (int)&g_b << endl; //Static variable static int s_a = 10; static int s_b = 10; cout << "Static variable s_a The address is: " << (int)&s_a << endl; cout << "Static variable s_b The address is: " << (int)&s_b << endl; cout << "The string constant address is: " << (int)&"hello world" << endl; cout << "The string constant address is: " << (int)&"hello world1" << endl; cout << "Global constant c_g_a The address is: " << (int)&c_g_a << endl; cout << "Global constant c_g_b The address is: " << (int)&c_g_b << endl; const int c_l_a = 10; const int c_l_b = 10; cout << "Local constant c_l_a The address is: " << (int)&c_l_a << endl; cout << "Local constant c_l_b The address is: " << (int)&c_l_b << endl; system("pause"); return 0; }
1.2 after program operation
- Stack area:
It is automatically allocated and released by the compiler to store the parameter values and local variables of the function
[note]: do not return the address of the local variable. The data opened up in the stack area is automatically released by the compiler
int * func() { int a = 10; return &a; } int main() { int *p = func(); cout << *p << endl;//a=10 will be output for the first time, because the compiler will automatically store the value of the local variable once cout << *p << endl;//The second output is garbled, because the compiler automatically releases the value of the local variable system("pause"); return 0; }
- Stacking area:
It is allocated and released by the programmer. If the programmer does not release it, it will be recycled by the operating system at the end of the program
In C + +, the new keyword is mainly used to open up memory in the heap
int* func() { int* a = new int(10); return a; } int main() { int *p = func(); cout << *p << endl; cout << *p << endl;//Constant output p=10 system("pause"); return 0; }
1.3 new operator
Using new operator in C + + to open up data in heap
The data developed in the heap area is manually developed by the programmer, manually released, and released by using the operator delete
Syntax: new data type
For the data created with new, the pointer of the type corresponding to the data will be returned
//Basic grammar int* func() { // Create integer data in heap // new returns a pointer to the data type int* a = new int(10); return a; } int main() { int *p = func(); cout << *p << endl; cout << *p << endl; //Using delete to release heap data delete p; //cout << *p << endl; // An error is reported. The free space is inaccessible system("pause"); return 0; }
//Heap array int main() { int* arr = new int[10]; for (int i = 0; i < 10; i++) { arr[i] = i + 100; } for (int i = 0; i < 10; i++) { cout << arr[i] << endl; } //Release array delete followed by [] delete[] arr; system("pause"); return 0; }
2 references
2.1 nature and basic grammar of reference
Essence: the essence of reference is implemented internally in c + +, which is a pointer constant
Function: alias variables,
Syntax: data type & alias = original name
int main() { int a = 10; int &b = a;//Operation on b is equivalent to operation on variable a cout << "a = " << a << endl; cout << "b = " << b << endl; // 10 // 10 b = 100; cout << "a = " << a << endl; cout << "b = " << b << endl; // 100 // 100 system("pause"); return 0; }
[note]:
- &(Reference) = = > used to transfer values. When it appears on the left of a variable in a variable declaration statement, it indicates that the declaration is a reference
- &(take address operator) = = > used to get the first address. It appears to the right of the equal sign when assigning an initial value to a variable or as a unary operator in an execution statement, indicating the address of the take object
//Nature of reference //Found to be a reference, converted to int * const ref = & A; void func(int& ref){ ref = 100; // Ref is a reference, converted to * ref = 100 } int main(){ int a = 10; //Automatically convert to int * const ref = & A; Pointer constants are pointer points that cannot be changed, which also explains why references cannot be changed int& ref = a; ref = 20; //It is found internally that ref is a reference, which is automatically converted to: * ref = 20; cout << "a:" << a << endl; cout << "ref:" << ref << endl; func(a); return 0; }
2.2 reference precautions
- Reference must be initialized
- The reference cannot be changed after initialization
int main() { int a = 10; int b = 20; //int &c; // Error, reference must be initialized int &c = a; //Once initialized, it cannot be changed c = b; //This is an assignment operation, not a change reference cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; // 20 // 20 // 20 system("pause"); return 0; }
2.3 reference function parameters
Function: when passing a function parameter, you can use the reference technology to make the formal parameter modify the argument
Advantages: pointer modification arguments can be simplified
//1. Value transfer void mySwap01(int a, int b) { int temp = a; a = b; b = temp; } //2. Address transfer void mySwap02(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } //Parameter: pass in the address and receive it with a pointer //3. Reference transfer void mySwap03(int& a, int& b) { int temp = a; a = b; b = temp; } //Parameter: alias. A below is the alias of a above. It can be modified by alias operation. The modification by original name operation is the same int main() { int a = 10; int b = 20; // Value passing, formal parameters do not modify arguments mySwap01(a, b); cout << "a:" << a << " b:" << b << endl; // a:10 b:20 // Address passing, formal parameters modify arguments mySwap02(&a, &b); cout << "a:" << a << " b:" << b << endl; // a:20 b:10 // When passed by reference, the formal parameter modifies the argument mySwap03(a, b); cout << "a:" << a << " b:" << b << endl; // a:10 b:20 system("pause"); return 0; }
2.4 reference function return value
Function: a reference can exist as the return value of a function
Note: do not return local variable references
Usage: function call as lvalue
//Returns a local variable reference //The data type is followed by &, which is equivalent to returning by reference int& test01() { int a = 10; //Local variables are stored in the stack area return a; } //Returns a static variable reference int& test02() { // Static variables are stored in the global area, and the data on the global area is released by the system after the program is completed static int a = 20; return a; } int main() { //Cannot return a reference to a local variable //Because local variables will be released automatically after operation int& ref = test01(); cout << "ref = " << ref << endl; cout << "ref = " << ref << endl; // The result is correct for the first time because the compiler has made reservations // The second result is wrong because a's memory has been released //If the function is an lvalue, it must return a reference int& ref2 = test02(); cout << "ref2 = " << ref2 << endl; cout << "ref2 = " << ref2 << endl; // 20 // 20 test02() = 1000; //The function call exists to the left of the equal sign: the function call is the left value cout << "ref2 = " << ref2 << endl; cout << "ref2 = " << ref2 << endl; // 1000 // 1000 system("pause"); return 0; }
2.5 constant reference
Function: constant reference is mainly used to modify formal parameters to prevent misoperation
In the function parameter list, const can be added to modify the parameter to prevent the parameter from changing the argument
//The scene used by reference is usually used to modify formal parameters void showValue(const int& v) { //If const is added, the formal parameters cannot be modified //v += 10; cout << v << endl; } int main() { //int& ref = 10; The reference itself requires a legal memory space, so this line of error //Just add const. The compiler optimizes the code. Int temp = 10; const int& ref = temp; const int& ref = 10; //ref = 100; // Variables cannot be modified after const is added cout << ref << endl; //Using constant reference in function to prevent misoperation and modify arguments int a = 10; showValue(a); system("pause"); return 0; }