SoFunction
Updated on 2025-03-03

In-depth analysis of global static storage areas, heap areas and stack areas

In C++, memory can be divided into system data area, free storage area, text area, const data area, global static area, heap area and stack area. Among them, the system data area stores system data, which we cannot access freely. Sometimes a message box will pop up suddenly in the Windows system, and the content is that "memory cannot be read" is the result of incorrect access to the system data area; the free storage area is used to store the data allocated by the malloc() function extended from C; the text area stores our function code, and the underlying behavior when we call the function is similar to operating a pointer first, and this pointer points to the address where the function instruction is located, that is, in the text area; the const data area, as the name implies, is the memory area that stores unmodified data, and the const variables we define are stored here. Finally, let’s look at the global static storage area, heap area and stack area.

Let’s first look at the global static storage area. In the program, the data defined by the static label is stored in the global static storage area. Whether it is a global variable defined outside the main() function or a local variable defined in a subfunction, as long as there is a static label before the definition, it will always exist in the global static storage area after definition. Of course, global static variables defined outside the main() function are accessible anywhere, while local static variables defined in subfunctions are only visible in the module that defines the variable. However, there is also a phenomenon: as mentioned earlier, even the local static variable defined in the subfunction has a static form, that is, after the variable definition statement is executed, even in the place where the variable is invisible, the value of the variable can be obtained by taking the address where the variable is located. For example, we define a static int a=100 in the function fun(); assuming that the address of the variable is 0x0042AD54, after we call fun() in the main() function, if we take the address resolution of 0x0042AD54, we can also get 100: int* p=(int*)0x0042ad54; int b=*p; Here b is assigned a value of 100. From this, we can see that the life cycle of any variable defined by static is the life cycle of the entire program. Until the program exits, the memory occupied by the static variables will be released.

The behavior of a heap storage area is similar to a static storage area. After we allocate memory on the heap, if we do not manually release it, its memory will not be automatically released. However, in JAVA, there is a mechanism called garbage cleaning that can automatically clean the heap memory, but there is no such mechanism in C++. That is, in C++, if we allocate heap memory, we have to release it manually. Otherwise, if we keep allocating heap memory but do not release it, the program will crash when the memory is exhausted.

Generally, variables allocated with new are stored in heap memory, but the returned pointer variables are stored in the stack. When we new a variable in a subfunction, but neither save the pointer returned by new or delete when the function returns, it will cause memory leakage. If we are writing a server program, the end result of constant memory leaks is the server crash. However, in Windows, Linux and some other mature systems, there are mechanisms similar to memory protection. The system will allocate a certain amount of memory required for operation to the user program, and will also retain a part of the memory for the system's own operation, which is not accessible to the user program. If there is a memory leak in the program we write, the program will stop running after exhausting the memory allocated to the application without causing the system driver.

As for stack memory, it is also the most used situation we use in writing programs. Each temporary object defined in the program, the pointer returned by new, and the variables in the recursive function are stored on the stack. Stack memory can be automatically released. When we define an object in a certain module, at the end of the module, the memory occupied by the variable will be recycled by the system. When defining a new variable, the new variable may be stored at the address where the original variable is located. However, when the system recycles the stack memory, the data in the released stack memory will not be cleared. It will only readjust the top of the stack and allocate it to the top of the stack when the new data arrives.

In C++, although memory can be operated freely, this technology is like a double-edged sword. If it is used well, it will cause some inexplicable results that you cannot understand. A deep understanding of how memory is allocated is of great benefit to actual programming.