before talking about function call and return value problem, let's look at the problem of memory allocation in C + +.
The C + + compiler divides computer memory into code areas and data areas, and it is clear that the code area is where the program code is stored, and the data area is the variables and constants that appear in the process of compiling and executing the program. The data area is divided into static data area, Dynamic Data area and dynamic Data area including heap area and stack area.
The following are the roles of each district:
(1) Code area: Store program code;
(2) Data area
A. Static data area: the memory allocated for the variable when the compiler compiles, and the data stored in this area is automatically released after all the execution of the program is completed, and the lifecycle runs through the whole process of execution.
B. Dynamic Data areas: including heap area and stack area
Heap area: This part of the storage space is entirely managed by the programmer itself, and its allocation and release are the responsibility of the programmer. This area is the only one that can be determined by the programmer to determine the lifetime of the variable. You can use Malloc,new to apply for memory, and free space by using the release and delete. If the programmer had applied for space in the heap area and had forgotten to release the memory, it would have caused a memory leak that would have prevented access to the storage area later.
Stack area: Store the form parameters and local variables of the function, which are allocated by the compiler and released automatically, and the space occupied by local variables and parameters will be released automatically when the function is finished. Efficiency is high, but the allocated capacity is limited.
Note:
1 Global variables and static variables are stored in the static data area;
2 attention to the storage area of the constants, typically, constants are stored in the program area (the program area is read-only, so any modification of the constants is illegal), not the data area. Some systems also assign some constants to static data areas, such as String constants (which are also assigned to the program area). Remember, however, that the memory space in which the constants reside is protected by the system and cannot be modified. Modification of the constant space will cause access to memory errors, the general system will prompt. The life cycle of a constant is until the end of the program execution.
After you understand the problem of memory allocation, look at the procedure of the function call:
When a function is executed, if there is a parameter, the space is allocated on the stack for the form parameter (outside of the argument of the reference type) and continues into the body of the function, and if the variable is encountered, the variable is allocated space in the different storage area (if it is a variable of the static type). is in the process of compiling has already allocated space), the function within the execution of the statement, if the function does not return a value, it returns directly to the place where the function is called (that is, the execution is far away), and if there is a return value, the return value is copied back, then the execution distance is returned, and after the function has been completed, the stack operation is performed. Release the memory space requested on the stack just inside the function.
Here are a few examples to talk about memory allocation and function return values :
Problem with memory allocation:
Copy Code code as follows:
int a=1; A in the stack area
Char s[]= "123"; s in the stack area, "123" in the stack area, and its value can be modified
Char *s= "123"; s in the stack area, "123" in the constant area, its value cannot be modified
int *p=new int; P in the Stack area, application space in the heap area (P-pointing area)
int *p= (int *) malloc (sizeof (int)); P in the Stack area, p-pointing space in the heap area
static int b=0; b in the static area
1.test1
Copy Code code 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=&a;
cout<<p<<endl;
Test (P);
cout<<p<<endl;
return 0;
}
The first and third rows of output are the same, while the first and third rows are different from the second row output. It can be seen from here that when a pointer is passed as a parameter it is only a value, except that the value is only one address, so changes to the formal parameter do not affect the argument.
2.test2
Copy Code code 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 may be Hello world!, or it may be a tangle.
This situation occurs because: the STR array declared inside the test function and its value "Hello World" is stored on the stack, and when the value of STR is returned with return, a copy of the STR value is sent back, and the space on the stack is automatically released when the test function finishes. That is, the unit that holds the Hello world may be rewritten to the data, so although the pointer p in the main function points to a unit that holds Hello World, there is no guarantee that the test function will be stored in Hello World after it is executed. So the printed results sometimes come from Hello World and in some cases it's a tangle.
3.test3
Copy Code code as follows:
#include <iostream>
using namespace Std;
int test (void)
{
int a=1;
return A;
}
int main (void)
{
int b;
B=test ();
cout<<b<<endl;
return 0;
}
Output is 1
Some people will ask why the value returned here can be printed correctly, is not the stack will be refreshed content? Yes, indeed, after the test function is done, a cell that holds a value is likely to be overridden, but when the function executes return, an int type zero is created, the value of a is copied to the zero variable, so the correct value is returned, even if the cell that holds a value is overwritten by the data, But it will not be affected.
4.test4
Copy Code code 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;
}
Execution result is Hello world!
Again, the pointer is returned, why is the Hello World1 printed correctly here? This is because char *p= "Hello world!" and the pointer p is stored on the stack, but "Hello world!" is a constant string, so it is stored in a constant area, and the lifetime of the variable in the constant area is the same as the lifetime of the entire program, so after the test function executes, str points to the "Hello world!" , and the contents of the unit are not modified until the program is executed, so the results can be output correctly.
5.TEST5
Copy Code code 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;
}
Run Results Hello World
In this case, you can also output the correct result, because it is using malloc on the heap of space, this part of the space is managed by the programmer, if the programmer does not manually release the heap area of space, then the contents of the storage unit will not be rewritten, so you can correctly output the results.
6.test6
Copy Code code 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
Notice here that free () releases the memory that the pointer points to! Attention! The memory is released, not the pointer! This is very, very important! The pointer is a variable that is destroyed only when the program ends. Freed the memory space, the original point to the space of the pointer is still there! But now the pointer points to the content of the garbage, is undefined, so that is rubbish. Therefore, after releasing the memory, you should point the pointer to null to prevent the pointer from accidentally being used, causing incalculable consequences.