1. SGI STL实现版本
SGI版本由Silicon Graphics Computer System, Inc公司发展,继承HP版本。所以它的每一个头文件也都有HP的版本声明。此外还加上SGI的公司版权声明。主要设计者仍然是STL之父Alexandar Stepanov,被Linux的C++编译器GCC所采用。SGI STL是开源软件,源码可读性非常高。
2. SGI STL的配置器与众不同,其名称为alloc,而且不用传任何参数,所以使用的时候必须写成:
vector<int , std::alloc> iv //in GCC
STL 标准规格告诉我们,配置器定义于<memory>之中,SGI <memory>内含以下两个头文件:
#include<stl_alloc.h>
#include<stl_construct.h>
具体分工如下图:
模拟实
现代码:
#pragma once namespace 51CC { template<class T> T* _allocate(ptrdiff_t size, T*) { //set_new_handler(0); T *tmp = (T*)(::operator new(size*sizeof(T))); if(tmp == 0) { cerr<<"Out Of Memory."<<endl; } return tmp; } template<class T> void _deallocate(T *buffer) { ::operator delete(buffer); } template<class T1, class T2> void _construct(T1 *p, const T2 &value) { new(p) T1(value); } template<class T> void _destroy(T *ptr) { ptr->~T(); } template<class T> class allocator { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; public: pointer allocate(size_type n, const void*hint = 0) { return _allocate(n, (pointer)0); } void deallocate(pointer p, size_type n) { _deallocate(p); } void construct(pointer p, const T &value) { _construct(p, value); } void destroy(pointer p) { _destroy(p); } }; };
construct() 和destroy()的示意图:
3. std::alloc中的一级及二级空间配置器模拟实现代码:
#pragma once #if 0 #include<new> #define __THROW_BAD_ALLOC throw bad_alloc #elif !defined(__THROW_BAD_ALLOC) //#include<iostream.h> #define __THROW_BAD_ALLOC cout<<"Out Of Memory."<<endl; exit(1) #endif template<int inst> class __malloc_alloc_template { public: static void* allocate(size_t n) { void *result = malloc(n); if(result == 0) result = b(n); // return result; } static void deallocate(void *p, size_t) { 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 = oom_realloc(p, new_sz); return result; } private: static void * oom_malloc(size_t n); static void * oom_realloc(void *p, size_t n); static void(*__malloc_alloc_oom_handler)(); }; template<int inst> void(* __malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = 0; template<int inst> void* __malloc_alloc_template<inst>::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>::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; } } ///////////////////////////////////////////////////////////////////////// enum {__ALIGN = 8}; enum {__MAX_BYTES = 128}; enum {__NFREELISTS = __MAX_BYTES / __ALIGN}; template<bool threads, int inst> class __default_alloc_template { public: static void *allocate(size_t n) { void *result; return result; } static void deallocate(void *p, size_t n); static void* reallocate(void *p, size_t old_sz, size_t new_sz); private: static size_t ROUND_UP(size_t bytes) { return (bytes+__ALIGN-1) & ~(__ALIGN-1);// } union obj { union obj * free_list_link; char client_data[1]; }; private: static size_t FREELIST_INDEX(size_t bytes) { return (bytes + __ALIGN - 1) / __ALIGN-1; } private: static obj * free_list[__NFREELISTS]; static char *start_free; static char *end_free; static size_t heap_size; }; template<bool threads, int inst> char* __default_alloc_template<threads, inst>::start_free = 0; template<bool threads, int inst> char* __default_alloc_template<threads, inst>::end_free = 0; template<bool threads, int inst> size_t __default_alloc_template<threads, inst>::heap_size = 0; //typename template<bool threads, int inst> __default_alloc_template<threads, inst>::obj* __default_alloc_template<threads, inst>::free_list[__NFREELISTS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
参考文献:STL源码剖析(简体)