Analyze the difference of memory allocation between stack area and heap area

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

I'm sure many of my friends have heard that memory is allocated on the stack and then on the heap. So what's the difference between them? To illustrate, let's first look at the internal organization of memory.

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201308/201308130909594.jpg ">


As can be seen from the figure above, the memory occupied by the program is divided into the following parts.

1. Stack
Assigned by the compiler automatically released, storage function of parameter values, the value of local variables, such as memory allocation is continuous, similar to what we call stack, if it is not clear, then to think of it as an array, it is continuous distribution of memory allocation, namely, allocated memory is in a contiguous area of memory. When we declare variables, the compiler automatically allocates memory at the end of the current stack area.

2. Heap area
Release is usually allocated by the programmer, if the programmer does not release, the end of the program may be recovered by the operating system. Similar to a linked list, the distributions in memory are not continuous, they are linked by Pointers to blocks of memory in different regions. Once a node is broken from the chain, we have to manually release the broken node from memory.

3. Global area (static area) (static)
Global variables and static variables are stored together, initialized global variables and static variables in one area, and uninitialized global variables and uninitialized static variables in another area adjacent to each other. When the program is finished, it is released by the system

4. Text constant area
That's where the constant string is. When the program is finished, it is released by the system

5. Program code area
The binary code that holds the body of the function.

Let's look at an example.
Char c; // allocation on the stack
Char *p = new char[3]; // allocated on the heap, assigned the address to p;

When the compiler encounters the first instruction, calculate the size, and then to find the current stack allocated space is greater than the required size, if this space is greater than the application within a stack space, then allocates memory space for it, note: here, the distribution of the inner space is continuous, then after the last distribution is distributed. If the space in the stack is smaller than the requested space size, then the system will reveal the stack overflow and give the corresponding exception information.

When the compiler encounters the second instruction, because p is allocated on the stack, it allocates the inner space for p in the same way as above, but when the new key is encountered, the compiler knows that this is the dynamic memory space requested by the user, so it goes to the heap to find the space allocation for it. Attention: the heap memory space is not continuous, it is by the corresponding list connect its inner blocks of space area, so the allocation of memory space specified after they receive, it will not immediately assigns corresponding space, but needed to calculate the space first, then to column again the whole heap (that is, through the whole chain of nodes), will be met for the first time the block of memory allocated to it. Finally, the first address of the array of characters allocated on the heap is assigned to p., at this point, it is clear that the first address of the array of characters applied in the heap is now assigned to the pointer variable p applied on the stack. To illustrate the problem more vividly, please see the following figure:

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201308/201308130909595.jpg ">

As you can see from the figure above, the first address of the array that we dynamically allocate on the heap stores what the pointer p points to.

Please note: The memory space on the stack are applying for, when we are out of the variable's scope, the system will automatically we recycle these Spaces, and on the heap application space, when the corresponding scope, we need to explicitly invoke delete to release the application memory space, if we don't have to release the space in time, the memory fragments in the memory is more and more, thus our actual memory space also becomes, the more to the less, that is, more and more isolated blocks of memory. Here, we know that in the heap memory area is not continuous, or effective memory area through the linked list pointer, if we apply to a block of memory, so a piece of memory will be from the continuous (through the linked list) on the memory block disconnect, if we are in after the use, not in time to release it, then it will be isolated, since there is no any pointer pointing to it, so this area will become the memory fragments, so after use of dynamically allocated memory (after) by NEW applications, must be explicitly to DELETE to DELETE it. For this, it's important to remember...

The above to state the concept between them, for their use of comparison, here I can not everyone intermittent statement, for this issue, a net friend's article in the more detailed, and with a professional color, the following article is part of the fragments.


Apply size limit
Stack: under Windows, a stack is a data structure that scales to a lower address and is a contiguous area of memory. In WINDOWS, the stack size is 2M (or 1M, a constant determined at compile time), and overflow will be prompted if the requested space exceeds the rest of the stack. Therefore, the amount of space available from the stack is small.

Pile: The heap is a data structure that extends to a high address and is a discrete area of memory. This is because the system USES the linked list to store the free memory address, is naturally discontinuous, and the list traversal direction is from the low address to the high address. The size of the heap is limited by the amount of virtual memory available in the computer system. Thus, the heap gains more flexible and larger space.

Comparison of application efficiency:
The stack is automatically allocated by the system and the speed is fast. But programmers can't control that.

The heap is memory allocated by new, which is generally slow and prone to fragmentation, but is the easiest to use.

In addition, under WINDOWS, the best way to allocate memory is with VirtualAlloc, which is not in the heap or on the stack but simply keeps a fast memory in the process's address space, although it is the least convenient to use. But it's fast and the most flexible.


The contents of the heap and stack
The stack:
When a function is called, the address of the next instruction in the main function (the next executable statement in the function call statement) is pushed first, followed by the parameters of the function, which in most C compilers are pushed from right to left, and then local variables in the function. Note that static variables are not pushed.

When the function call is over, the local variable is pushed out of the stack first, then the argument, and finally the top pointer on the stack points to the original address, which is the next instruction in the main function, and the program continues to run from that point.

Pile: The size of the heap is usually stored in one byte at the head of the heap. The details of the heap are arranged by the programmer.

Comparison of access efficiency
Char [] s1 = "aaaaaaaaaaaaaaa";
Char * s2 = "BBBBBBBBBBBBBBBBB";

Aaaaaaaaaaa is assigned at runtime;
BBBBBBBBB is determined at compile time;
However, in later accesses, the array on the stack is faster than the string that the pointer points to, such as the heap.

Such as:


void main()
{
    char a = 1;
    char c[] = "1234567890";
    char *p ="1234567890";
    a = c[1];
   a = p[1];
    return;
}

The corresponding assembly code

10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al

The first reads the elements of the string directly into the register cl, while the second reads the pointer values into the edx first, which is obviously slow to read the characters from the edx.

Summary:
The difference between a heap and a stack can be seen in the following analogy:
The use of the stack is like we go to a restaurant to eat, just order (issued applications), pay, and eat (use), eat enough to go, do not have to pay attention to the preparation work such as cutting, washing dishes, washing POTS and other finishing work, his advantage is fast, but less freedom.

Using the heap is like cooking the dishes you like to eat by yourself, more troublesome, but more in line with your own taste, and freedom


Related articles: