ADDRESS:Bldg A8, Xiashiwei 1st Industrial Zone
Fuyong, Baoan District, Shenzhen, Guangdong, PRC
One of the main reasons to define a custom allocator is to improve performance. Using a dedicated custom allocator can improve program performance, or improve memory usage efficiency, or both. The default allocator uses the new operator to allocate storage space, which is often implemented using the C language heap allocation function (malloc()). Since the heap allocation function is often optimized for sporadic memory allocations, the default allocator is generally efficient when allocating memory for containers that need to allocate large amounts of memory at once (eg, vector, deque). However, for associative containers and doubly-linked lists, which need to allocate a small amount of memory frequently, if the default allocator allocates memory, it is usually inefficient. In addition, the default allocator based on malloc() has many problems, such as poor referential locality, and may cause memory fragmentation.
In view of this, in this case, people often use memory pool-based allocators to solve the problem of frequent small allocations. Unlike the default "assignment on demand" method, when using a memory pool based allocator, the program will allocate a large amount of memory ("memory pool") in advance, and then when the need to allocate memory, the custom allocator only A pointer to the memory in the pool needs to be returned to the requester. When the object is destructed, it is not necessary to actually deallocate the memory. Instead, the real deallocation is delayed until the end of the life cycle of the memory pool.
On the topic of “Custom Dispenser”, many C++ experts and related authors have already participated in discussions, such as Scott Meyers’s “Effective STL” and Andre Alexandre Rescu’s "Modern C + + Design" has been mentioned. Meyers insights that if all instances of a dispenser for a certain type T are required to be equal, instances of portable dispensers must contain no state. Although the C++ standard encourages library implementers to support stateful dispensers, Meyers said that the relevant paragraphs are "(looks like) a wonderful point of view," but are almost empty words, and claim that the distributor restrictions are "too harsh ". For example, STL's list allows the splice method, ie a node of list object A can be moved directly into another list object B. This requires that the memory allocated by A's allocator can be freed by the B's allocator, thus deriving The distributor instances for A and B must be equal. Myers concludes that the distributor is best defined as a type that uses static methods. For example, according to the C++ standard, allocators must provide a template of other class that implements the rebind method.
In addition, in the "C + + Programming Language", Bianni Strawstrup believes that "'strictly restricting the distributor, so as not to different information of each object', this is obviously not a problem" (to the effect), and It is pointed out that most distributors do not need state, and even if there is no state, the performance is better. He proposed three custom dispenser use cases: a memory pool type, a shared memory type, and a garbage collection type, and demonstrated the implementation of a splitter, using an internal memory pool for quickness. Allocate/Deallocate a small amount of memory. However, he also mentioned that such optimization may have been implemented in the sample distributor he provided.
Another use of the custom allocator is to debug memory-related errors. To do this, you can write an allocator that allocates additional memory when it is allocated and use it to store debugging information. This type of allocator not only guarantees that the memory is allocated/de-allocated by the same type of allocator, but also protects the program from buffer overflow to some extent.