首页 > 代码库 > STL源码剖析:空间配置器
STL源码剖析:空间配置器
看完自己重写了一下,不知道的又看了一遍,里面没有考虑多线程的问题,主要是想实现以下内存池。
Mempool.h
#ifndef MEMPOOL_H_ #define MEMPOOL_H_ #include <cstddef> #include <new> #include <cstdlib> namespace flysnow { enum {STEP_ = 8}; enum {MAX_BYTES_ = 128}; enum {FREELIST_NUM_ = MAX_BYTES_/STEP_}; class Mempool{ private: union pool_bucket { union pool_bucket* next_node; char bucket_addr[1]; }; static size_t up_to_nearest(size_t n) { return STEP_*((n>>3) + (n%8 ? 1:0)); } static size_t freelist_index(size_t n) { return ((n>>3) + (n%8 ? 0:-1)); } static void* refill(size_t n); static char* alloc_memory(size_t size,int &pool_node_num); static pool_bucket* free_list_[FREELIST_NUM_]; static char* start_pool; static char* end_pool; static size_t heap_size; public: static void* allocate(size_t n); static void deallocate(void *p,size_t n); static size_t get_heap_size() {return heap_size;} }; } #endif
Mempool.cpp
#include "mempool.h" namespace flysnow{ char* Mempool::start_pool = 0; char* Mempool::end_pool = 0; size_t Mempool::heap_size = 0; Mempool::pool_bucket* Mempool::free_list_[FREELIST_NUM_] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; void* Mempool::allocate(size_t n) { if(n > MAX_BYTES_){ return malloc(n); } pool_bucket *p; pool_bucket **free_list_index = free_list_ + freelist_index(n); p = *free_list_index; if(0 == p) { void *q = refill(up_to_nearest(n)); return q; } *free_list_index = p->next_node; return p; } void Mempool::deallocate(void *p,size_t n) { pool_bucket *q = (pool_bucket*)p; if(n > MAX_BYTES_) { free(p); return ; } pool_bucket **free_list_index = free_list_ + freelist_index(n); q->next_node = *free_list_index; *free_list_index = q; } void* Mempool::refill(size_t n) { int pool_node_num = 20; int i; pool_bucket **free_list_index = free_list_ + freelist_index(n); char *pool = alloc_memory(n,pool_node_num); if(1 == pool_node_num) { return pool; } pool_bucket *result = (pool_bucket*)pool; pool_bucket *current,*next; pool += n; *free_list_index = next = (pool_bucket*)pool; next = (pool_bucket*)pool; for(i=1; ;++i){ current = next; next = (pool_bucket*)((char*)next + n); if(pool_node_num - 1 == i){ current->next_node = NULL; break; } else { current->next_node = next; } } return result; } char* Mempool::alloc_memory(size_t size,int &pool_node_num) { size_t total_size = size*pool_node_num; size_t remain_size = end_pool - start_pool; if(total_size <= remain_size) { char* result = start_pool; start_pool += total_size; return result; } else if(remain_size >= size) { pool_node_num = remain_size/size; size_t return_size = pool_node_num*size; char *result = start_pool; start_pool += return_size; return result; } else { size_t get_size = 2*total_size + up_to_nearest(heap_size>>4); if(remain_size > 0) { //如果剩余7byte,此处会放在8byte的自由链表中,然而,最后allocate 8byte的 //时候,岂不会出错? //原来之前get_size分配的内存总是8的倍数,因此不会出现以上情况。。。。 pool_bucket **free_list_index = free_list_ + freelist_index(remain_size); ((pool_bucket*)start_pool)->next_node = *free_list_index; *free_list_index = (pool_bucket*)start_pool; } start_pool = (char*)malloc(get_size); if(0 == start_pool) { pool_bucket **free_list_index; pool_bucket *p; for(int i=size;i<=MAX_BYTES_;i+=STEP_) { free_list_index = free_list_ + freelist_index(i); p = *free_list_index; if(0 != p) { *free_list_index = p->next_node; start_pool = (char*)p; end_pool = start_pool + i; return (alloc_memory(size,pool_node_num)); } } end_pool = 0; start_pool = (char*)malloc(get_size); } heap_size += get_size; end_pool = start_pool + get_size; //return (alloc_memory(size,pool_node_num)); char *result = start_pool; start_pool += total_size; return result; } } }
main.cpp
#include <iostream> #include "mempool.h" using namespace std; int main() { char *p; for(size_t i=0;i<100000;++i){ p = (char*)flysnow::Mempool::allocate(i%1029+1); cout<<flysnow::Mempool::get_heap_size()<<' '; } cout << endl; system("PAUSE"); return 0; }
STL源码剖析:空间配置器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。