标签:point hand trait 配置 接受 char oid throw 执行
C++STL的空间配置器将内存的分配、释放,对象的构造、析构都分开执行,内存分配由alloc::allocate()负责,内存的释放由alloc::deallocate()负责;对象的构造由::construct()负责,对象的析构由::destroy()负责。
下面为源码和注释:
#include <new.h> //使用placement new
//使用placement new在已经分配的内存上构造对象
template <class T1, class T2>
inline void construct(T1* p, const T2& value) {
new (p) T1(value);
}
//第一个版本,接受一个指针
//调用对象的析构函数,它需要有non-trivial destructor
template <class T>
inline void destroy(T* pointer) {
pointer->~T();
}
//第二个版本
//针对迭代器为char*和wchar_t*的特化版本
inline void destroy(char*, char*) {}
inline void destroy(wchar_t*, wchar_t*) {}
//接受两个迭代器,找出元素的类型
template <class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last) {
__destroy(first, last, value_type(first));
}
//判断元素的类型是否有trivial destructor
template <class ForwardIterator, class T>
inline void __destroy(ForwardIterator first, ForwardIterator last, T*) {
typedef typename __type_traits<T>::has_trivial_destructor trivial_destructor;
__destroy_aux(first, last, trivial_destructor());
}
//元素的类型有non-trivial destructor
template <class ForwardIterator>
inline void
__destroy_aux(ForwardIterator first, ForwardIterator last, __false_type) {
for ( ; first < last; ++first)
destroy(&*first);
}
//元素的类型有trivial destructor
template <class ForwardIterator>
inline void __destroy_aux(ForwardIterator, ForwardIterator, __true_type) {}
在内存配置方面,STL分为两级配置器,当请求的内存大于128bytes的时候调用第一级配置器,当请求的内存小于等于128bytes的时候调用第二级配置器。如图:
第一级配置器源码:
template <int inst>
class __malloc_alloc_template {
private:
static void *oom_malloc(size_t);
static void *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 = 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 = 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);
}
};
// malloc_alloc out-of-memory handling
#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>::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);
}
}
标签:point hand trait 配置 接受 char oid throw 执行
原文地址:https://www.cnblogs.com/vlyf/p/11838458.html