STL memory Creation
Owed by: spring night rain http://blog.csdn.net/chunyexiyu reprint please indicate the source
1.Create a base class template in STL memory_ Malloc_alloc_template
Reference file for memory creation in STL: stl_alloc.h, which defines the _ malloc_alloc_template template library. Use the C method malloc, free, and realloc to create and release the template library. The template library mainly provides external functions:
Allocate: Memory Allocation
Deallocate: releases memory
Reallocate: realallocates memory.
_ Set_malloc_handler: sets the exception handling function.
Template <int _ inst> Class _ malloc_alloc_template { PRIVATE: Static void * _ s_oom_malloc (size_t ); Static void * _ s_oom_realloc (void *, size_t ); # Ifndef _ stl_static_template_member_bug Static void (* _ malloc_alloc_oom_handler )(); # Endif Public: Static void * allocate (size_t _ n) { Void * _ result = malloc (_ n ); If (0 = _ result) _ result = _ s_oom_malloc (_ n ); Return _ result; } Static void deallocate (void * _ p, size_t/* _ n */) { Free (_ P ); } Static void * reallocate (void * _ p, size_t/* old_sz */, size_t _ new_sz) { Void * _ result = realloc (_ p, _ new_sz ); If (0 = _ result) _ result = _ s_oom_realloc (_ p, _ new_sz ); Return _ result; } Static void (* _ set_malloc_handler (void (* _ f )()))() { Void (* _ old) () = _ malloc_alloc_oom_handler; _ Malloc_alloc_oom_handler = _ F; Return (_ old ); } }; |
1. Memory Allocation and release
Use malloc and realloc to allocate memory. To handle memory allocation exceptions, the two static methods passed to the Template Library:
_ S_oom_malloc
_ S_oom _ realloc
If you use free to release the memory, there is no exception in the memory release. You can call the free pointer directly and the imported size_t is not used.
2. Allocate Exception Handling
For details about how to handle memory allocation exceptions, refer to the implementation in _ s_oom_malloc/_ s_oom_realloc.
In implementation, you can throw an exception or execute the agreed processing function (such as the memory organizing function) and continue to apply for memory.
The following functions involve function pointers:
_ Malloc_alloc_oom_handler
This function specifies the method _ malloc_alloc_template :__ set_malloc_handler
If this function is not specified, call exception _ throw_bad_alloc for processing.
Under a. c ++, STD: bad_alloc () is thrown (),
Print and terminate the program to the standard output in B. C: fprintf (stderr, "out of memory \ n"); exit (1)
If this function is specified, it refers to this function (such as the memory organizing function), and then applies for the memory again until the application is successful, and the requested memory address is returned:
_ My_malloc_handler = _ malloc_alloc_oom_handler;
(* _ My_malloc_handler )();
_ Result = malloc (_ n );
If (_ result) Return (_ result );
# Ifndef _ throw_bad_alloc # If defined (_ stl_no_bad_alloc) |! Defined (_ stl_use_exceptions) # Include <stdio. h> # Include <stdlib. h> # DEFINE _ throw_bad_alloc fprintf (stderr, "out of memory \ n"); exit (1) # Else/* standard conforming out-of-memory handling */ # Include <New> # DEFINE _ throw_bad_alloc throw STD: bad_alloc () # Endif # Endif # Ifndef _ stl_static_tembian _ member_bug Template <int _ inst> Void (* _ malloc_alloc_template <__ inst >::__ malloc_alloc_oom_handler) () = 0; # Endif Template <int _ inst> Void * _ Malloc_alloc_template <__inst>: _ s_oom_malloc (size_t _ n) { Void (* _ my_malloc_handler )(); Void * _ result; For (;;){ _ My_malloc_handler = _ malloc_alloc_oom_handler; If (0 = _ my_malloc_handler) {_ throw_bad_alloc ;} (* _ My_malloc_handler )(); _ Result = malloc (_ n ); If (_ result) Return (_ result ); } } Template <int _ inst> Void * _ malloc_alloc_template <__inst>: _ s_oom_realloc (void * _ p, size_t _ n) { Void (* _ my_malloc_handler )(); Void * _ result; For (;;){ _ My_malloc_handler = _ malloc_alloc_oom_handler; If (0 = _ my_malloc_handler) {_ throw_bad_alloc ;} (* _ My_malloc_handler )(); _ Result = realloc (_ p, _ n ); If (_ result) Return (_ result ); } } |
3. encapsulated allocation methods
A. simple_alloc, with the check 0/null operation appended
Template <class _ TP, class _ alloc> Class simple_alloc { Public: Static _ TP * allocate (size_t _ n) {Return 0 = _ n? 0: (_ TP *) _ alloc: allocate (_ n * sizeof (_ TP ));} Static _ TP * allocate (void) {Return (_ TP *) _ alloc: allocate (sizeof (_ TP ));} Static void deallocate (_ TP * _ p, size_t _ n) {If (0! = _ N) _ alloc: deallocate (_ p, _ n * sizeof (_ TP ));} Static void deallocate (_ TP * _ p) {_ Alloc: deallocate (_ p, sizeof (_ TP ));} }; |
B. When debug_alloc is allocated each time, an 8-byte space is added to store the size currently allocated.
// Allocator adaptor to check size arguments for debugging. // Reports errors using assert. Checking can be disabled // Ndebug, but it's far better to just use the underlying Allocator // Instead when no checking is desired. // There is some eviify that this can confuse purify. Template <class _ alloc> Class debug_alloc { PRIVATE: Enum {_ s_extra = 8}; // size of space used to store size. Note // That this must be large enough to preserve // Alignment. Public: Static void * allocate (size_t _ n) { Char * _ result = (char *) _ alloc: allocate (_ n + (INT) _ s_extra ); * (Size_t *) _ result = _ n; Return _ result + (INT) _ s_extra; } Static void deallocate (void * _ p, size_t _ n) { Char * _ real_p = (char *) _ p-(INT) _ s_extra; Assert (* (size_t *) _ real_p = _ n ); _ Alloc: deallocate (_ real_p, _ n + (INT) _ s_extra ); } Static void * reallocate (void * _ p, size_t _ old_sz, size_t _ new_sz) { Char * _ real_p = (char *) _ p-(INT) _ s_extra; Assert (* (size_t *) _ real_p = _ old_sz ); Char * _ result = (char *) _ Alloc: reallocate (_ real_p, _ old_sz + (INT) _ s_extra, _ New_sz + (INT) _ s_extra ); * (Size_t *) _ result = _ new_sz; Return _ result + (INT) _ s_extra; } }; |
4. Memory Allocation Information Storage Class Allocator
// This implements allocators as specified in the C ++ standard. // // Note that standard-conforming allocators use special language features // That are not yet widely implemented. In particle, they rely on // Member templates, partial specialization, partial ordering of Function // Templates, The typename keyword, and the use of the template keyword // To refer to a template member of a dependent type. # Ifdef _ stl_use_std_allocators Template <class _ TP> Class Allocator { Typedef alloc _ alloc; // The underlying allocator. Public: Typedef size_t size_type; Typedef ptrdiff_t difference_type; Typedef _ TP * pointer; Typedef const _ TP * const_pointer; Typedef _ TP & reference; Typedef const _ TP & const_reference; Typedef _ TP value_type; Template <class _ TP1> struct rebind { Typedef Allocator <_ TP1> Other; }; Allocator () _ stl_nothrow {} Allocator (const Allocator &) _ stl_nothrow {} Template <class _ TP1> Allocator (const Allocator <_ TP1> &) _ stl_nothrow {} ~ Allocator () _ stl_nothrow {} Pointer address (reference _ x) const {return & __x ;} Const_pointer address (const_reference _ x) const {return & __x ;} // _ N is permitted to be 0. The C ++ standard says nothing about what // The return value is when _ n = 0. _ TP * allocate (size_type _ n, const void * = 0 ){ Return _ n! = 0? Static_cast <_ TP *> (_ alloc: allocate (_ n * sizeof (_ TP ))) : 0; } // _ P is not permitted to be a null pointer. Void deallocate (pointer _ p, size_type _ n) {_ Alloc: deallocate (_ p, _ n * sizeof (_ TP ));} Size_type max_size () const _ stl_nothrow {Return size_t (-1)/sizeof (_ TP );} Void construct (pointer _ p, const _ TP & _ Val) {New (_ p) _ TP (_ Val );} Void destroy (pointer _ p) {_ p-> ~ _ TP ();} }; |
STL Memory Allocation