Before talking about function calls and return values, let's take a look at the issue of memory allocation in C ++.
The C ++ compiler divides computer memory into code and data areas. Obviously, the code area stores program code, the data zone stores the variables and constants in the compilation and execution processes of the program. The data zone is divided into static data zone and Dynamic Data zone. The dynamic data zone includes the heap zone and stack zone.
The role of each zone is as follows:
(1) code area: stores program code;
(2) Data Zone
A. static Data zone: the memory allocated to the variable during compilation by the compiler. The data stored in this zone is automatically released after all programs are executed, the life cycle runs through the entire program execution process.
B. Dynamic Data zone: including heap zone and stack Zone
Heap zone: This part of the storage space is managed by the programmer himself, and its distribution and release are all the responsibility of the programmer himself. This zone is the only one where the programmer can decide the lifetime of the variable. You can use malloc and new to apply for memory and release space through free and delete. If the programmer applies for space in the heap area and forgets to release the memory, it will cause memory leakage and will not be able to access the storage area.
STACK: stores the form parameters and local variables of the function, which are allocated and automatically released by the compiler. After the function is executed, the space occupied by the local variables and parameters is automatically released. Efficiency is relatively high, but the allocated capacity is very limited.
Note:
1) global variables and static variables are stored in the static data zone;
2) Pay attention to the storage area of constants. Normally, constants are stored in the program area (the program area is read-only, so any behavior to modify constants is illegal), rather than the data area. Some systems also allocate some constants to static data areas, such as string constants (some systems also allocate them to the program area ). Remember that the memory space of a constant is protected by the system and cannot be modified. Modifying the constant space will cause access to memory errors. Generally, the system will prompt you. The life cycle of a constant until the execution of the program ends.
After learning about the memory allocation problem, let's take a look at the function call process:
When a function is executed, if a parameter exists, space is allocated for the form parameter on the stack (if it is a parameter of the reference type, it is out of class) and continues to enter the function body. If a variable is encountered, allocate space for variables in different storage areas as needed (for static variables, space is allocated during compilation ), after the statement in the function is executed, if the function does not return a value, it directly returns the place where the function is called (that is, the execution is far away). If the return value exists, the return value is copied and returned first, return to the execution point. After all the functions are executed, perform the stack rollback operation to release the memory space applied for in the function stack.
Here are a few examples to talk about memory allocation and function return values:
Memory Allocation Problems:
Copy codeThe Code is as follows: int a = 1; a is in the stack Zone
Char s [] = "123"; s is in the stack zone, "123" is in the stack zone, and its value can be modified
Char * s = "123"; s is in the stack zone, "123" is in the constant zone, and its value cannot be modified.
Int * p = new int; p is in the stack zone, and the applied space is in the heap zone (p points to the zone)
Int * p = (int *) malloc (sizeof (int); p in the stack area, p points to the space in the heap Area
Static int B = 0; B is in the static Zone
1. test1 Copy codeThe Code is as follows: # include <iostream>
Using namespace std;
Void test (int * p)
{
Int B = 2;
P = & B;
Cout <p <endl;
}
Int main (void)
{
Int a = 10;
Int * p = &;
Cout <p <endl;
Test (p );
Cout <p <endl;
Return 0;
}
The output results of the first and third rows are the same, but the output results of the first and third rows are different from those of the second row. It can be seen from this that when the pointer is passed as a parameter, only one value is passed, but the value is only one address. Therefore, the change of the parameter does not affect the real parameter.
2. test2
Copy codeThe Code is as follows: # include <iostream>
Using namespace std;
Char * test (void)
{
Char str [] = "hello world! ";
Return str;
}
Int main (void)
{
Char * p;
P = test ();
Cout <p <endl;
Return 0;
}
The output result may be hello world !, It may also be messy.
The reason for this is that the str array declared in the test Function and Its Value "hello world" are saved on the stack. when return is used to return the str value, copy the str value and send it back. After the test function is executed, the space on the stack is automatically released, that is, the hello world unit may be rewritten into the data, therefore, although the pointer p in the main function points to the unit that stores hello world, it cannot be ensured that after the test function is executed, the Unit still stores hello world, therefore, the output result is sometimes hello world or messy.
3. test3
Copy codeThe Code is as follows: # include <iostream>
Using namespace std;
Int test (void)
{
Int a = 1;
Return;
}
Int main (void)
{
Int B;
B = test ();
Cout <B <endl;
Return 0;
}
The output result is 1.
Some people may ask why the values returned here can be correctly printed, not the stack will be refreshed? Yes. Indeed, after the test function is executed, the unit that stores the value may be overwritten. However, when the function executes return, a zero-time variable of the int type will be created, copy the value of a to the zero-time variable. Therefore, the correct value can be obtained after the return result. Even if the unit storing the value of a is overwritten, the data will not be affected.
4. test4
Copy codeThe Code is as follows: # include <iostream>
Using namespace std;
Char * test (void)
{
Char * p = "hello world! ";
Return p;
}
Int main (void)
{
Char * str;
Str = test ();
Cout <str <endl;
Return 0;
}
The execution result is hello world!
Again, a pointer is returned. Why is hello world1 correctly printed here? This is because char * p = "hello world! ", Pointer p is stored on the stack, but" hello world !" It is a constant string, so it is stored in the constant area, and the lifetime of the variable in the constant area is the same as that in the whole program execution. Therefore, after the test function is executed, str points to store "hello world!" And the content in the unit will not be modified when the program is not executed, so the results can be output correctly.
5. test5
Copy codeThe Code is as follows: # include <iostream>
Using namespace std;
Char * test (void)
{
Char * p = (char *) malloc (sizeof (char) * 100 );
Strcpy (p, "hello world ");
Return p;
}
Int main (void)
{
Char * str;
Str = test ();
Cout <str <endl;
Return 0;
}
Running result hello world
In this case, the correct results can also be output because the space applied for on the stack is malloc, which is managed by the programmer. If the programmer does not manually release the space in the stack, the content in the storage unit will not be overwritten, so the results can be correctly output.
6. test6
Copy codeThe Code is as follows: # include <iostream>
Using namespace std;
Void test (void)
{
Char * p = (char *) malloc (sizeof (char) * 100 );
Strcpy (p, "hello world ");
Free (p );
If (p = NULL)
{
Cout <"NULL" <endl;
}
}
Int main (void)
{
Test ();
Return 0;
}
No output
Note that free () releases the memory pointed to by the pointer! Note! Memory is released, not a pointer! This is very, very important! A pointer is a variable and is destroyed only when the program ends. After the memory space is released, the pointer to this space still exists! But now the Pointer Points to the content of the garbage, is undefined, so said garbage. Therefore, after the memory is released, the pointer should be directed to NULL to prevent the pointer from being accidentally used and causing incalculable consequences.