码迷,mamicode.com
首页 > 其他好文 > 详细

STL之空间配置器allocator

时间:2019-11-11 21:57:44      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:point   hand   trait   配置   接受   char   oid   throw   执行   

摘要

C++STL的空间配置器将内存的分配、释放,对象的构造、析构都分开执行,内存分配由alloc::allocate()负责,内存的释放由alloc::deallocate()负责;对象的构造由::construct()负责,对象的析构由::destroy()负责。

构造和析构: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) {}

空间的配置和释放: std::alloc

在内存配置方面,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);
    }
}

STL之空间配置器allocator

标签:point   hand   trait   配置   接受   char   oid   throw   执行   

原文地址:https://www.cnblogs.com/vlyf/p/11838458.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!