A detailed explanation of the difference between static storage and stack and heap in C++

  • 2020-04-02 01:06:21
  • OfStack

Learning c++ without understanding memory allocation is a very sad thing. Moreover, it can be said that a C++ programmer who cannot master memory, can not understand memory, can not be a qualified C++ programmer.
1. Basic structure of memory
Programmable memory is basically divided into several parts: static storage, heap, and stack. Their functions differ, so do the ways they are used.
Static storage: An embedded program is allocated when it is compiled, and the embedded program exists for the duration of its run. It mainly stores static data, global data, and constants.
The stack area: When a function is executed, the storage locations of local variables within the function can be created on the stack, and these storage locations are automatically released at the end of the function execution. The stack memory allocation operation is built into the processor's instruction set, which is efficient, but the allocated memory capacity is limited.
The heap area: Also known as dynamic memory allocation. The program requests any size of memory with malloc or new while it is running, and the programmer is responsible for freeing memory with free or delete when appropriate. The lifetime of dynamic memory can be determined by us, and if we don't free the memory, the program will free the dynamic memory at the end. However, a good programming practice is that if a dynamic memory is no longer in use, it needs to be freed, otherwise we think there is a memory leak.

Two, the difference between the three
Let's take a look at the code snippet to see what needs to be done and different for these three parts of memory, and what we should pay attention to.
Example 1: static storage area and stack area


    char* p =  " Hello World1 "; 
    char a[] =  " Hello World2 "; 
    p[2] = ' A' ; 
    a[2] = ' A' ; 
    char* p1 =  " Hello World1 ;" 

There is an error in this program, the error occurs in the line p[2] = 'A', why, the variable p and the variable array A both exist in the stack (any temporary variables are in the stack, including the variables defined in the main () function). However, the data "Hello World1" and the data "Hello World2" are stored in different regions. Because the data "Hello World2" exists in the array, this data is stored in the stack and there is no problem modifying it. Because the pointer variable p can only store the address of a storage space, the data "Hello World1" is a string constant, so it is stored in a static storage area. Although p[2] gives access to a third data cell in the static store, the cell in which the character 'l' resides. But because the data "Hello World1" is a string constant and cannot be changed, memory errors are reported when the program runs. Also, if you print p and p1, you will find that the address stored in p and p1 is exactly the same.
Example 2: stack area and heap area

char* f1 (a)  
  {  
 char* p = NULL ;   
 char a ;    
 p =    return p ;   
  }  

 char* f2 (a)    
 {  
  char* p = NULL :   
  p = ( char* ) new char[4] ;  
   return p ;    
 }  

Both of these functions return the address of a storage space, so what's the difference? The f1 () function returns a storage space, but this space is temporary. In other words, this space has only a short life cycle, its life cycle at the end of the function f1 () call, it lost its life value, that is, the space is freed. So, when calling the f1 () function, if the program has the following statement:

    char* p ; 
    p = f1 (a); 
    *p = ' a' ; 

At this point, compilation does not report errors, but exception errors occur while the program is running. Because, you are operating on memory (that is, memory space that has been freed) that you should not be operating on. However, by comparison, the f2 () function doesn't have any problems. Because the new command is to request storage space in the heap, once the application is successful, unless you delete it or terminate the program, this memory will always exist. It is also understood that heap memory is a Shared unit that can be accessed by multiple functions. Heap memory is a good choice if you need to have multiple data returns and have no way out. But be sure to avoid the following:

   void f (a) 
    {
     ... 
    char * p ; 
    p = ( char* ) new char[100] ; 
     ... 
    }

This program does something that is meaningless and harmful. Because, although heap memory is requested, p saves the first address of the heap memory. However, this variable is temporary and disappears when the function call ends. That is, there are no variables to store the first address of this heap memory, and we will never be able to use that heap memory again. However, this heap memory is always marked as being used by you (because you did not delete it until the end of the program, so the heap memory is always marked as being owned by your program), and therefore cannot be used by other processes or programs. This unethical "hooliganism" (we don't use it, but we don't let anyone else use it) is called a memory leak.

In summary, the biggest difference between the heap, stack, and static storage areas is that the stack lifecycle is short. But the life cycle of the heap and static storage is the same as the life of the program (if you don't delete the heap memory while the program is running), and we call this variable or data a global variable or data. However, the use of memory space in the heap is more flexible because it allows you to free it up when you don't need it, whereas the static storage will remain for the entire life of the program.


Related articles: