![这里写图片描述](https://img-blog.csdn.net/20170507173035003?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUFJPR1JBTV9hbnl3aGVyZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
注释的STL代码,算是为将来复习做个小笔记吧
#if 0
#include<new>
#define __THROW_BAD_ALLOC throw std::bad_alloc()
#elif !defined(__THROW_BAD_ALLOC)
#include<iostream>
#define __THROW_BAD_ALLOC std::cerr<<"out of memory"<<std::endl; exit(1)
#endif
template<int inst>
class __malloc_alloc_template
{
private:
static void *oom_malloc(size_t n)
{
void(*my_malloc_handler)() = NULL;
void *result = NULL;
for (;;)
{
my_malloc_handler = __malloc_alloc_oom_handler;
if (NULL == my_malloc_handler)
{
__THROW_BAD_ALLOC;
}
(*my_malloc_handler)();
result = malloc(n);
if (NULL != result)
return result;
}
}
static void *oom_realloc(void *p, size_t n)
{
void(*my_malloc_handler)() = NULL;
void *result = NULL;
for (;;)
{
my_malloc_handler = __malloc_alloc_oom_handler;
if (NULL == my_malloc_handler)
{
__THROW_BAD_ALLOC;
}
(*my_malloc_handler)();
result = realloc(p, n);
if (NULL != result)
return result;
}
}
static void(*__malloc_alloc_oom_handler)();
public:
static void *allocate(size_t n)
{
void * result = malloc(n);
if (result == NULL)
{
result = oom_malloc(n);
}
return result;
}
static void deallocate(void *p, size_t)
{
free(p);
}
static void *reallocate(void *p, size_t , size_t new_sz)
{
void *result = realloc(p, new_sz);
if (NULL == result)
{
result = 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;
}
};
typedef __malloc_alloc_template<0> malloc_alloc;
#if 0
template<int inst>
void(*__malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = NULL;
#else
char *preMem = new char[1024 * 1024 * 10];
void delPreMem()
{
delete preMem;
}
template<int inst>
void(*__malloc_alloc_template<inst>::__malloc_alloc_oom_handler)() = delPreMem;
#endif
enum { __ALIGN = 8 };
enum { __MAX_BYTES = 128 };
enum { __NFREELISTS = __MAX_BYTES / __ALIGN };
template<bool threads, int inst>
class __default_malloc_template
{
private:
union obj
{
union obj * free_list_link;
char client_data[1];
};
static obj * volatile free_list[__NFREELISTS];
static size_t ROUND_UP(size_t bytes)
{
return (bytes + __ALIGN - 1) & ~(__ALIGN - 1);
}
static size_t FREELIST_INDEX(size_t bytes)
{
return ((bytes + __ALIGN - 1) >> 3) - 1;
}
static char * start_free;
static char * end_free;
static size_t heap_size;
static char *chunk_alloc(size_t size, int &nobjs)
{
char * result = NULL;
size_t total_bytes = size * nobjs;
size_t bytes_left = end_free - start_free;
if (bytes_left >= total_bytes)
{
result = start_free;
start_free += total_bytes;
return result;
}
else if (bytes_left >= size)
{
nobjs = bytes_left / size;
total_bytes = size*nobjs;
result = start_free;
start_free += total_bytes;
return result;
}
else
{
size_t bytes_to_get = 2 * total_bytes + ROUND_UP(heap_size >> 4);
if (bytes_left > 0)
{
obj * volatile * my_free_list = free_list + FREELIST_INDEX(bytes_left);
((obj*)start_free)->free_list_link = *my_free_list;
*my_free_list = (obj*)start_free;
}
start_free = (char*)malloc(bytes_to_get);
if (NULL == start_free)
{
int i;
obj * volatile * my_free_list,*p;
for (i = size; i <= __MAX_BYTES; i += __ALIGN)
{
my_free_list = free_list + FREELIST_INDEX(i);
p = *my_free_list;
if (NULL != p)
{
*my_free_list = p->free_list_link;
start_free = (char *)p;
end_free = start_free + i;
return chunk_alloc(size, nobjs);
}
}
start_free = (char*)malloc_alloc::allocate(bytes_to_get);
}
heap_size += bytes_to_get;
end_free = start_free + bytes_to_get;
return chunk_alloc(size, nobjs);
}
}
static void *refill(size_t n)
{
int nobjs = 20;
char * chunk = chunk_alloc(n, nobjs);
obj * result = NULL;
obj * current_obj, *next_obj;
int i;
if (nobjs == 1)
return chunk;
obj * volatile * my_free_list = free_list + FREELIST_INDEX(n);
result = (obj*)chunk;
*my_free_list = next_obj = (obj*)(chunk + n);
for (i = 1;; ++i)
{
current_obj = next_obj;
next_obj = (obj*)((char*)next_obj + n);
if (i == nobjs - 1)
{
current_obj->free_list_link = NULL;
break;
}
current_obj->free_list_link = next_obj;
}
return result;
}
public:
static void *allocate(size_t n)
{
obj * volatile * my_free_list = NULL;
obj * result = NULL;
if (n > (size_t)__MAX_BYTES)
{
return malloc_alloc::allocate(n);
}
my_free_list = free_list + FREELIST_INDEX(n);
result = *my_free_list;
if (NULL == result)
{
void *r = refill(ROUND_UP(n));
return r;
}
*my_free_list = result->free_list_link;
return result;
}
static void deallocate(void *p, size_t n)
{
obj * volatile * my_free_list = NULL;
obj * q = (obj*)p;
if (n > (size_t)__MAX_BYTES)
{
malloc_alloc::deallocate(p, n);
return;
}
my_free_list = free_list + FREELIST_INDEX(n);
q->free_list_link = *my_free_list;
*my_free_list = q;
}
static void *reallocate(void *p, size_t old_sz, size_t new_sz)
{
void * result;
size_t copy_sz;
if (old_sz > (size_t)__MAX_BYTES && new_sz > (size_t)__MAX_BYTES)
{
return(malloc_alloc::reallocate(p, old_sz, new_sz));
}
if (ROUND_UP(old_sz) == ROUNDP_UP(new_sz))
return(p);
result = allocate(new_sz);
copy_sz = new_sz > old_sz ? old_sz : new_sz;
memcpy(result, p, copy_sz);
deallocate(p, old_sz);
return(result);
}
};
template<bool threads, int inst>
typename __default_malloc_template<threads, inst>::obj * volatile
__default_malloc_template<threads, inst>::free_list[__NFREELISTS] = { NULL };
template<bool threads, int inst>
char * __default_malloc_template<threads, inst>::start_free = NULL;
template<bool threads, int inst>
char * __default_malloc_template<threads, inst>::end_free = NULL;
template<bool threads, int inst>
size_t __default_malloc_template<threads, inst>::heap_size = 0;
#ifdef __USE_MALLOC
typedef __malloc_alloc_template<0> malloc_alloc;
typedef malloc_alloc alloc;
#else
typedef __default_malloc_template<0, 0> alloc;
#endif
template<class T, class Alloc>
class simple_alloc
{
public:
static T * allocate(size_t n)
{
return n == 0 ? NULL : (T*)Alloc::allocate(n * sizeof(T));
}
static T * allocate()
{
return (T*)Alloc::allocate(sizeof(T));
}
static void deallocate(void *p, size_t n)
{
if (n == 0) return;
Alloc::deallocate(p, n*sizeof(T));
}
static void deallocate(void *p)
{
Alloc::deallocate(p, sizeof(T));
}
};