The "dynamic memory" here includes the following two aspects:
1. Memory. The "Memory" here refers to the virtual memory space of the process. In a Win32 environment, each process is independent of 4G (0x0000 0000 ~ 0 xFFFF FFFF.
2. Dynamic. Here "dynamic" refers to the dynamic memory area in the virtual memory space of the process. In the virtual memory space of a process, only the dynamic memory can be freely allocated, used, and released by the application during running.
In the Win32 environment, we can use multiple methods to allocate/use/release dynamic memory. These methods include:
1. Win32 APIs. These APIs include virtualxxx (), heapxxx (), localalloc (), and globalalloc ().
2. c run-time library. These functions include malloc () and free ().
3. Keywords new and delete provided by C ++.
With so many memory allocation methods, we are often confused when learning and coding in actual projects. Are their internal implementations the same? What are the essential differences between them? What are their respective use cases? This article attempts to explore their nature in depth to provide a basis for correct understanding and use of them.
First, we 'd better grasp the relationship between them from a global perspective. Here is a good description of the hierarchical relationship between them:
This figure gives us a panoramic view. We can see the hierarchical relationship between them clearly from this figure:
Level 1: Win32 API, as a system interface, provides a set of interfaces for operating virtual memory;
Layer 2: heap is a part of the virtual memory. Win32 API provides a set of interfaces for operating the heap memory. However, these interfaces are based on the interfaces for operating the virtual memory.
Layer 3: The C run-time library on Windows uses heap APIs to implement malloc and free.
We can see that there is a single hierarchical relationship between these dynamic memory operations. The lowest layer of this layer is the virtual memory API, it can be said that these methods are built on the virtual memory API. The following describes the differences between virtual memory APIs:
1. Virtual Memory API
As the "core" interface for Virtual Memory operations provided by windows, virtual memory APIs should be the most common among several methods, it is also the most powerful method. For more information about the use of virtual memory APIs, see Programming Application for Windows (by Jeffrey Richter)
Ii. heap memory API
When learning the process memory space "image", we also mentioned the concept of "Heap, at that time, "Heap" refers to a memory segment (segment) dynamically allocated by the application at runtime, and other memory segments (segment, data segment, stack segment, etc) memory space of the process. Here, "Heap" refers to an object owned by a process (there are many objects in windows, such as window, icon, and brush). When we create a heap object, we can get the handle of this object, then we can use this handle to use dynamic memory, and finally destroy this object.
Iii. localalloc/globalalloc
These two functions are two legacy functions in Win16 API. Win32 API only contains these two functions to maintain compatibility. These two functions use the heap memory API to operate a "special" heap object: The default heap object of the process. Each process creates a default heap object during initialization and destroys the default heap object at the end of the process. The difference between localalloc and gblobalalloc is only manifested in the Win16 environment. In the Win16 environment, the memory address is obtained through the segment: Segment offset, localalloc () memory can only be allocated within the same segment, while globalalloc can access the memory Across the segment boundary. In the Win32 environment, there is no such restriction on memory access, so they show the same function. Since the heap memory API can fully implement both of them, we do not recommend using these two functions in Win32.
4. malloc/free
These two functions are the two most frequently used functions, which are highly portable because they are part of the standard C library. Here "portability" means that their code can be compiled on different platforms, while the specific implementation of C run-time library on different platforms is platform-related, the malloc () and free () in the C run-time library on windows are implemented by calling the heap memory API. It is worth noting that the C run-time Library has an independent heap object. We know that when an application is initialized, the C run-time library is initialized first, then there is the entry function of the application, and the heap object is created when the C run-time library is initialized. For dynamic-linked C run-time libraries, the Runtime Library is initialized only once, and for static-connected runtime libraries, each link is initialized once, therefore, the runtime libraries of each static link have different heap objects. In this way, problems may occur in some situations, causing program crash. For example, an application calls multiple DLL, except one DLL, other DLL, the application itself dynamically connects to the runtime so that they use the same heap object. A dll uses a static connection Runtime Library, which has a heap object different from other DLL. When the dll exists and is released in another DLL, the problem arises.
5. Keywords new/keyword Delete
These two words are the built-in keywords (keyword) of C ++ ). When the C ++ compiler sees the keyword new, for example:
Cmyobject * pobj = new cmyobject;
The compiler executes the following two tasks:
1. Allocate necessary memory dynamically on the stack. This task is completed by a global function void *: Operator new (size_t) provided by the compiler. It is worth noting that any class can reload this global function. If the class reloads this function, the one that is reloaded by the class will be called.
2. Call the constructor of cmyclass to initialize the newly generated object. Of course, if the assigned object is the basic data type in C ++, no constructor call will be performed.
If you want to go deep into the global function void *: Operator new (size_t), we will find that its specific implementation is to allocate memory by calling malloc.
With this analysis, we have a higher understanding of these dynamic memory allocation methods and can use them correctly in our code.
References:
1. Programming Application for Windows (by Jeffrey Richter)
2. Windows System Programming Third Edition (by Johnson M. HART)
3. Here is an article on the difference between localalloc and globalalloc from the perspective of "History": http://blogs.msdn.com/oldnewthing/archive/2004/11/01/250610.aspx
At home
V1.1
1. Modified the content of the keyword new/delete in this article. Previously, the keyword new and function void * operator new (size_t) were mixed.
At home