[Programming language] a comprehensive summary of heap and stack, and a comprehensive summary of Programming Language
Stack in the operating system:
A function is automatically allocated and released by the compiler. A function corresponds to a stack and is used to store the parameter values of the function, return values after the function is called, and local variables in the function body. The stack occupies a continuous segment of memory space, and its operation and organization are very similar to the stack in the data structure. Stack is the memory space reserved for execution threads. When a function is called, the stack is created. When the function execution is complete, the stack is recycled.
Heap in the operating system:
The programmer manually applies for and releases the memory. Since the memory blocks manually applied by programmers and released are stored in the heap, there are many memory blocks in the heap, the heap is organized in a similar way as a linked list. The heap in the operating system is completely different from the heap in the data structure. In my opinion, the common understanding is as follows: the heap in the data structure is a "structure Heap" with rigorous logic and operation methods, while the heap in the operating system is, it is more like connecting a bunch of messy things with a linked list. A heap is a reserved memory space for Dynamic Allocation. its lifecycle is the entire application lifecycle. After the application ends, the heap starts to be recycled.
Each thread has its own stack, but each application usually has only one heap (one application uses multiple heap ). When a thread is created, the stack size is set. Set the heap size when the application starts. The stack size is usually fixed, but the heap can be expanded as needed, such as when programmers apply for more memory from the operating system.
Since the stack works in a way similar to the stack in the data structure, and the stack works in a way similar to a linked list, the stack is obviously much faster than the stack. According to the stack access method, to release memory or add new memory, you only need to move the top pointer of the stack. Heap needs to first find a suitable memory space in the idle area of the memory, then occupy it, and then point to this space. Obviously, heap is much more complicated than stack.
Next, I wanted to separate the stack from the stack, and decided to compare the stack and stack from the same aspect. It is more obvious.
1. The stack size is fixed when the stack is created, because the stack needs to occupy a space continuously. According to the features of the heap, the size of the heap is dynamic, and its allocation and release are also dynamic.
2. Too much data in the stack will lead to an explosion of stacks, such as dfs write. And if the heap is also exploding... That means the memory is also exploding.
3. Each function stack is independent, but the stack of an application is shared by all stacks. Since sharing is mentioned, there is a problem of "parallel access. In fact, parallel access is controlled by the stack instead of the stack.
4. The stack scope is limited to the function, and the stack will release its own space when the function ends. However, the variables created on the heap must be manually released. The variables in the heap do not have a scope issue because the heap is global.
5. The stack stores the function return value addresses, function parameters, and local variables in the function. The heap stores memory blocks (such as malloc and new) manually applied by programmers ).
6. Heap and stack are allocated as needed. The stack has a strict capacity ceiling, while the stack capacity ceiling is "not strict. The heap does not have a fixed capacity limit. It is related to the current amount of memory remaining (in fact, it is not accurate. The operating system also has virtual memory or other concepts, so the heap's working method is abstract ).
7. The stack memory can be allocated by moving the top pointer of the stack. By allocating memory on the heap, you can find an area of sufficient size from the idle memory, just like the working method of the linked list.
8. As long as the stack capacity is not exceeded, the stack can be freely released and applied for memory, which does not cause memory problems and is secure. Different from the heap, a large number of applications and releases of small memory blocks may cause memory problems. These small memory blocks are scattered in the memory, leading to failure in subsequent Memory application, because although the idle memory is enough, it is not consecutive. In this case, the small memory is called "heap fragments ". However, this is not a big problem. For more information, see "Operating System.
9. After the stack bottom address is determined, the top pointer of the stack starts from the bottom address and gradually moves to the lower address. That is to say, the storage space of the stack is from high address to low address. On the contrary, when applying for space, the heap usually looks for available memory in the high address direction.
Pure text descriptions seem boring. Let's look at some code:
#include <iostream>using namespace std;void func(){ int i = 5; int j = 3; int k = 7; int *p = &i; printf("%d\n", *p); printf("%d\n", *(p-1)); printf("%d\n", *(p-2));}int main(){ func(); getchar(); return 0;}
The result of the above Code is: 5 3 7
We can see two things from the results:
First, the stack address is continuous. We can use a pointer and a relative size to "offset" other variables.
Second, we can see that the stack address is distributed from high to low, and the stack bottom is in the direction of high address and low address. Therefore, the program uses the P-1 instead of the p + 1.
Void func () {int * p = NULL; // The upstream code is important. This pointer will be used to apply for new memory. // In this case, except that the variable itself occupies 4 bytes of Space (the pointer occupies 4 bytes), no other space is applied. // This pointer variable is a local variable of the function, so it is created on the stack. Int num = 100; // This variable is also created on the stack. Int buffer [100]; // Similarly, buffer occupies the space of 400 bytes of the stack p = new int [100]; // note that the programmer has manually applied for a space, the 400 bytes of memory is created on the stack. // At this moment, p is in the state: p is the local variable of the function and points to a global memory space .} // The function body ends. The above function has a serious problem, that is, the memory leakage of the pointer p. // The correct method is to delete the memory at the end of the function, or return the address of the memory for further use.
Next, let's take a look at what happens when a function is called:
First, the operating system allocates a stack for this function, because after calling this function, it must be able to correctly return to the next statement and continue execution, so the first step is to push the address of the next instruction that calls the function to the stack. In this way, when the function call is complete and the top pointer of the stack releases the memory a little bit, the top pointer of the stack points to this address, and then it returns to the correct position for further execution.
int main(){func();printf("%d\n", 100);return 0;}
For example, before calling func, we first put the next statement of func, that is, the address of the printf Statement, in the stack. In this way, after the function is called, the printf will be returned correctly and executed later. Note that the address here is the instruction address, not the variable address or something. It is similar to the Program Counter (PC, that is, Program Counter) in the operating system ). Then, the real parameters are sequentially added to the stack from right to left (most C/C ++ compilers are from right to left), followed by various local variables in the function. Note that the static variables in the function are not included in the stack. Global variables and static variables have been configured with memory in static storage during compilation.
If the function calls other functions at this time, the process is the same. First, the return address, and then the parameters and local variables. In this way, when the call at each layer ends and the top pointer of the stack continuously drops (the memory is released), it will be able to correctly return to the previously called position and continue to execute.
The process of getting out of the stack, or releasing memory, is the opposite according to the stack features, so we will not go into details.
In a C or C ++ program, the memory address in its eyes is divided into five areas:
Stack, heap, static, text constant, and program command.
The stack and stack zones have already been introduced. The Global static zone is used to store global variables and static variables. The Global static zone is divided into two parts: one is used for the global variables and static variables after initialization, and the other is used for uninitialized global variables and static variables. The Global static zone is the same as the heap. After the program ends, the operating system releases it. The text constant area is used to store the constant string. After the program ends, it is released by the operating system. It is best to understand the program instruction area, that is, the binary instruction that stores the program code.
Int cnt; // int num = 0 in the uninitialized zone of the Global static zone; // int * p in the initialized zone of the Global static zone; // The uninitialized int main () {int I, j, k stored in the Global static zone; // The int * pBuffer = (int *) stored in the stack Zone *) malloc (sizeof (int) * 10); // the pointer pBuffer is in the stack. The heap contains char * s = "hactrox"; // the pointer s is stored in the stack, string is stored in the text constant area char str [] = "hactrox"; // str and string are stored in the stack static int a = 0; // a is stored in the initialized area of the global static zone}
Char * s = "hactrox"; // "hactrox" in the text constant area, s points to "hactrox" in this area, so this can be understood, create the string in the text constant area, and then s points to the string. S itself is stored as a local variable in the stack.
// The following code is incorrect. Is the pointer assigned directly before it is pointed?
Int * p = 5;
// The following code is correct. First, create the int type variable, and then point p to the variable. Int variables from new are in the heap.
Int * p = new int (5 );
Next let's take a look at a very common problem: Is there any problem with the following code? Where is the problem?
#include <iostream>using namespace std;char* f1(){ char *s = "hactrox"; return s;}char* f2(){ char s[] = "hactrox"; return s;}int main(){ printf("%s\n", f1()); printf("%s\n", f2()); getchar(); return 0;}
The problem is that the second function, f2 does not correctly return that string. In function f1, the "hactrox" string is created in the text constant area and returns the address of the constant string, because the string in the text constant area is global, although the pointer s is a local variable, however, s has sent the target address before it disappears, so s's extinction is not the focus. The focus is that the returned address is still pointing to the region, so it can be correctly displayed. In function f2, "hactrox" and "s" are local variables and they are stored in the stack. Although s returns an address, the memory pointed to by this address has been released. The address is valid, but the target is invalid. The output is garbled.
There are still some things to talk about in the text constant area (as if it is far from the topic of this blog ?)
# Include <iostream> using namespace std; void func () {char * str1 = "123"; printf ("% x \ n", str1 ); char * str2 = "123"; // in the same text constant area, the compiler may direct str2 to the memory pointed to by str1, // instead of opening up a new space to store the second identical string. // Print the str2 pointer to verify printf ("% x \ n", str2); char * s1 = "hactrox"; printf ("% x \ n ", s1); char * s2 = "hactrox"; printf ("% x \ n", s2);} int main () {func (); getchar (); return 0 ;}
Char s [] = "hactrox ";
Char * s = "hactrox again ";
The second code, that is, the variable in the text constant zone has been determined during compilation,
The first code is assigned a value during running.
In this way, it seems that the efficiency of the second code is high, but it is not,
When these two variables are used at runtime, For the first code, the string is directly read. For the second code, the string pointer is read first, and then the string is read Based on the pointer, obviously, the efficiency is reduced.
In fact, I think the focus on stacks and stacks is mainly on scope, lifecycle, and validity.
The pointer is released, which does not mean that the memory pointed to by the pointer is released. Similarly, the memory to which the Pointer Points is released does not mean that the pointer is released synchronously or automatically pointing to NULL. the pointer still points to the Invalid Address. This address cannot be used. No one can guarantee what will happen next to an Invalid Address.
What is the difference between stack and stack?
In computer science, a stack is a linear table that is only inserted or deleted at the end of a table.
Stack is a data structure. It stores data based on the principle of "first-in-first-out". The first data is pushed to the bottom of the stack, and the last data is placed at the top of the stack, data is popped up from the top of the stack when data needs to be read (the last data is read by the first one ).
Stack is a special linear table that can only be inserted and deleted at one end. Pile up items in a bucket, first pile in under pressure, then one piece to pile up. Only one of the above items can be taken when you take the data. The heap and fetch operations are carried out on the top, and the bottom is usually not moving.
Stack is a data structure similar to bucket accumulation items. One End for deletion and insertion is called the stack top, and the other is called the stack bottom. Insert is generally called PUSH and delete is called POP ). Stack is also known as a post-import, first-out table (LIFO table ).
In a program, the heap is used to dynamically allocate and release objects used by the program. Call the heap operation in the following cases:
1. Do not know the number and size of objects required by the program in advance.
2. The object is too large to use the stack distributor.
The heap uses the memory allocated to parts other than the code and stack during runtime.
Traditionally, the operating system and Runtime Library are accompanied by a heap implementation. When a process starts, the operating system creates a default heap called a process heap. If no other heap is used, process heap is used to allocate blocks. The Language Runtime Library can also create a separate heap in a process. (For example, the C Runtime Library creates its own heap .) In addition to these dedicated heaps, applications or one of many loaded Dynamic Link Libraries (DLL) can also be created and used separately. Win32 provides a rich set of APIS for creating and using private stacks. For an excellent tutorial on heap functions, see the SDK node on the MSDN platform.
When an application or DLL creates a dedicated heap, these heaps reside in the process space and are accessible within the process range. Any data allocated to a given heap should be released from the same heap. (Allocating from one heap and releasing it to another is meaningless .)
In all virtual memory systems, the heap is located on the Virtual Memory Manager of the operating system. The Language Runtime heap also resides on the virtual memory. In some cases, these stacks are on the upper layer of the Operating System Heap, but the language runtime heap manages its memory by allocating large blocks. Using Virtual Memory functions without Operating System Heap allows the heap to allocate and use blocks better.
A typical heap implementation consists of a front-end distributor and a backend distributor. The front-end distributor maintains a free list of fixed size blocks. When the heap receives the allocation call, it tries to find the free block from the front-end list. If this operation fails, the heap will be forced to allocate a large block from the backend (Reserve and submit the virtual memory) to satisfy the request. The general implementation has the overhead of each block allocation, which takes the execution cycle and reduces the available storage zone.
The implementation of Windows NT (Windows NT version 4.0 and later) uses a Free List of 127 8-byte alignment blocks ranging from 8 to 1,024 bytes and a hybrid list. The hybrid list (Free List [0]) contains blocks larger than 1,024 bytes. The Free List contains objects linked together in a two-way link table. By default, the process heap performs the merge operation. (Merge operations combine adjacent free blocks to generate larger blocks .) The merge operation takes an additional period, but reduces the internal fragmentation of the heap block.
A single global lock prevents multiple threads from using heap at the same time. This lock is mainly used to protect the heap data structure from arbitrary access by multiple threads. When the heap operation is too frequent, this lock will negatively affect the performance.
What is the stack in computer language?
[Edit this section] What is a stack?
In the computer field, stack is a concept that cannot be ignored, but many people, even computer professionals, do not know that stack is actually two data structures.
A stack is a data structure in which data items are arranged in order. Data items can be inserted and deleted only at one end (called the top.
Key points:
Heap: random order
STACK: Last-In/First-Out)
[Edit this section] stack and stack differences
I. prerequisites-program memory allocation
The memory occupied by a c/C ++ compiled program is divided into the following parts:
1. stack: the stack zone is automatically allocated and released by the compiler, and stores function parameter values and local variable values. The operation method is similar to the stack in the data structure.
2. heap-generally assigned and released by the programmer. If the programmer does not release the heap, it may be recycled by the OS at the end of the program. Note that it is different from the heap in the data structure. The allocation method is similar to the linked list.
3. Global (static)-the storage of global variables and static variables is put together, and the initialized global variables and static variables are in one area, uninitialized global variables and uninitialized static variables are in another adjacent area. -The program is released by the system after it is completed.
4. Text Constant Area-constant strings are placed here. The program is released by the system.
5. program code area-stores the binary code of the function body.
Ii. Example Program
This is written by a senior. It is very detailed.
// Main. cpp
Int a = 0; global initialization Zone
Char * p1; uninitialized globally
Main ()
{
Int B; stack
Char s [] = "abc"; stack
Char * p2; stack
Char * p3 = "123456"; 123456 \ 0 is in the constant zone, and p3 is in the stack.
Static int c = 0; Global (static) initialization Zone
P1 = (char *) malloc (10 );
P2 = (char *) malloc (20 );
}
The allocated 10-byte and 20-byte areas are in the heap area.
Strcpy (p1, "123456"); 123456 \ 0 is placed in the constant area, and the compiler may optimize it into a place with the "123456" that p3 points.
[Edit this section] theoretical knowledge about heap and stack
1. Application Method
Stack:
Automatically assigned by the system. For example, declare a local variable int B in the function; the system automatically opens up space for B in the stack.
Heap:
The programmer needs to apply and specify the size. In c, the malloc Function
For example, p1 = (char *) malloc (10 );
Use the new operator in C ++
For example, p2 = new char [20]; // (char *) malloc (10 );
But note that p1 and p2 are in the stack.
2. system response after application
STACK: as long as the remaining space of the stack exceeds the applied space, the system will provide the program with memory. Otherwise, an exception will be reported, prompting stack overflow.
Heap: First, you should know that the operating system has a linked list that records idle memory addresses. When the system receives a program application, it will traverse the linked list, find the heap node with the first space greater than the requested space, delete the node from the idle node linked list, and allocate the space of the node to the program. In addition, for most systems, the size of the allocation will be recorded at the first address in the memory space, so that the delete statement in the code can correctly release the memory space. In addition, because the size of the heap node is not necessarily equal to the applied size, the system automatically places the excess part in the idle linked list.
3. Restrictions on application size... the remaining full text>