STL内存分配
?
1.??????Stl內(nèi)存創(chuàng)建基類模板__malloc_alloc_template
STL的常用的內(nèi)存創(chuàng)建參考文件: stl_alloc.h,文件中定義了__malloc_alloc_template模板庫,創(chuàng)建與釋放使用C方法malloc、free、realloc,模板庫里面主要對外提供了函數(shù):
allocate:?分配內(nèi)存
deallocate:?釋放內(nèi)存
reallocate:?重新分配內(nèi)存
__set_malloc_handler:?設(shè)置異常處理函數(shù)
| 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); ? } ? }; |
?
2.?? 內(nèi)存分配與釋放
使用malloc和realloc分配內(nèi)存,對于分配內(nèi)存異常的處理,模板庫中交給內(nèi)部的這兩個靜態(tài)方法:
_S_oom_malloc
_S_oom_ realloc
?
使用free釋放內(nèi)存,對于釋放內(nèi)存來說,是無異常處理的,直接調(diào)用free指針,傳入的size_t未使用。
?
3?? 分配異常處理
分配內(nèi)存的異常處理方法,參考_S_oom_malloc/_S_oom_realloc中的實現(xiàn)
在實現(xiàn)中或者是通過拋出異常,或者是通過執(zhí)行約定的處理函數(shù)(如內(nèi)存整理函數(shù)),然后繼續(xù)申請內(nèi)存。
在下面的函數(shù)中,涉及了函數(shù)指針:
__malloc_alloc_oom_handler
這個函數(shù)指定方法__malloc_alloc_template ::__set_malloc_handler
?
如果這個函數(shù)未指定的話,調(diào)用異常__THROW_BAD_ALLOC處理
a.?? C++下,拋出std::bad_alloc(),
b.?? C下,向標(biāo)準(zhǔn)輸出中打印并終止程序: fprintf(stderr, "out of memory\n"); exit(1)
?
如果這個函數(shù)指定的話,指行這個函數(shù)(例如內(nèi)存整理函數(shù)),然后再次申請內(nèi)存,直到成功申請到后返回申請到的內(nèi)存地址:
__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_TEMPLATE_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); ??? } } |
?
4.?? 封裝的幾組分配方式
a.?? Simple_alloc,附加了檢查0/NULL的操作
| ? 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.?? debug_alloc每次分配時,多附加8字節(jié)的空間,用于存儲當(dāng)前分配的size大小。
| // Allocator adaptor to check size arguments for debugging. // Reports errors using assert.? Checking can be disabled with // NDEBUG, but it's far better to just use the underlying allocator // instead when no checking is desired. // There is some evidence 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; ? } ? }; |
?
?
5.?? 內(nèi)存分配類allocator/__allocator
allocator分配類使用缺省的分配類(alloc),使用分配類的靜態(tài)方法。
__allocator類需要輸入分配類,并對分配類實例化了對像,調(diào)用對像的分配方法分配內(nèi)存。
a)?? allocator
| ? // This implements allocators as specified in the C++ standard.? // // Note that standard-conforming allocators use many language features // that are not yet widely implemented.? In particular, 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(); } }; |
?
?
b)?? __allocator
可以傳入不同的分配方式,另外實例化了對像,支持對象內(nèi)記錄分配字節(jié)等,屬于對復(fù)雜分配方式的支的。
__allocator最大的特點,實例化了分配對像
| // Allocator adaptor to turn an SGI-style allocator (e.g. alloc, malloc_alloc) // into a standard-conforming allocator.?? Note that this adaptor does // *not* assume that all objects of the underlying alloc class are // identical, nor does it assume that all of the underlying alloc's // member functions are static member functions.? Note, also, that // __allocator<_Tp, alloc> is essentially the same thing as allocator<_Tp>. ? template <class _Tp, class _Alloc> struct __allocator { ? _Alloc __underlying_alloc; ? ? 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, _Alloc> other; ? }; ? ? __allocator() __STL_NOTHROW {} ? __allocator(const __allocator& __a) __STL_NOTHROW ??? : __underlying_alloc(__a.__underlying_alloc) {} ? template <class _Tp1> ? __allocator(const __allocator<_Tp1, _Alloc>& __a) __STL_NOTHROW ??? : __underlying_alloc(__a.__underlying_alloc) {} ? ~__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. ? _Tp* allocate(size_type __n, const void* = 0) { ??? return __n != 0 ??????? ? static_cast<_Tp*>(__underlying_alloc.allocate(__n * sizeof(_Tp))) ??????? : 0; ? } ? ? // __p is not permitted to be a null pointer. ? void deallocate(pointer __p, size_type __n) ??? { __underlying_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(); } }; |
?
?
?
6.?? 內(nèi)存分配結(jié)構(gòu)體
這個結(jié)構(gòu)體很有意思,
參數(shù)一:?_S_instanceless標(biāo)識包含有allocator_type定義
參數(shù)二:?_Alloc_type,簡單分配方式,simple_alloc調(diào)用_Alloc的靜態(tài)方法進行分配釋放內(nèi)存
參數(shù)三: ?allocator_type,可支持復(fù)雜分配方式,實例化了_Alloc對像,使用對象方法分配釋放內(nèi)存,支持對象內(nèi)包含分配的總數(shù),或其它附加信息,可以在對像內(nèi)實現(xiàn)內(nèi)存池等。
| template <class _Tp, class _Alloc> struct _Alloc_traits<_Tp, debug_alloc<_Alloc> > { ? static const bool _S_instanceless = true; ? typedef simple_alloc<_Tp, debug_alloc<_Alloc> > _Alloc_type; ? typedef __allocator<_Tp, debug_alloc<_Alloc> > allocator_type; }; |
?
總結(jié)
- 上一篇: TCP端口扫描方式
- 下一篇: open,write,read与fope