stl allocator源码学习

本文深入探讨了STL allocator的源码实现,包括最简单的实现、VS2015中的实现、STLport的实现以及带内存池的实现。详细讲解了allocator的rebind机制,以及内存分配函数如_Aallocate和_Deallocate的实现。还介绍了静态断言static_assert的用法,并分析了内存池在提高内存利用率方面的作用。
摘要由CSDN通过智能技术生成

概述

介绍几个allocator的源码实现:简单的对operator new和operator delete进行封装的实现,vs2015中的实现,STLport中的实现,仿造STLport实现内存池。

1. 参考

http://www.cplusplus.com/reference/memory/allocator/
《STL源码剖析》
《C++ Primer 第五版》
《Generic Programming and the STL》(《泛型编程和STL》)
MSDN

2. 介绍

std::allocator是STL容器使用的内存配置器,也是标准库唯一预定义的内存配置器。

3. 实现一:最简单的实现

3.1 程序实现

template<class T>
class allocator
{
public:
    // 1、为什么需要下面这些成员,有什么作用呢?
    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;       // size_t是无符号整数
    // ptrdiff_t是有符号整数,代表指针相减结果的类型
    typedef ptrdiff_t  difference_type;

    // 2、这是做什么用的,为何template是U,而不是与allocator的T一致?
    template<class U>
    struct rebind
    {
        typedef allocator<U> other;
    };

    // 默认构造函数,什么都不做
    allocator() noexcept
    {
    }

    // 泛化的构造函数,也什么都不做
    // 3、为什么需要这个泛化的构造函数,不同类型的allocator复制合适吗?
    template<class U>
    allocator(const allocator<U>&) noexcept
    {
    }

    // 析构函数,什么都不做
    ~allocator() noexcept
    {
    }

    // 返回对象地址
    pointer address(reference val) const noexcept
    {
        //non-const版调用const版,参见《Effective C++》条款3
        return const_cast<reference>(address(static_cast<const_reference>(val)));
    }

    // 返回对象地址
    const_pointer address(const_reference val) const noexcept
    {
        return &val;
    }

    // 申请内存,count是指对象个数,不是字节数。
    // 4、hint是做什么的?
    pointer allocate(size_type count, allocator<void>::const_pointer hint = nullptr)
    {
        return static_cast<pointer>(::operator new(count * sizeof(value_type)));
    }

    // 释放内存
    void deallocate(pointer ptr, size_type count)
    {
        ::operator delete(ptr);
    }

    // 可配置的最大量(指对象个数,不是字节数)
    size_type max_size() const noexcept
    {
        return (static_cast<size_type>(-1) / sizeof(value_type));
    }

    // 构造对象,Args是模板参数包,见《C++ Primer》第5版16.4节
    template <class U, class... Args>
    void construct(U* p, Args&&... args)
    {
        ::new ((void *)p) U(::std::forward<Args>(args)...);
    }

    // 析构对象
    template <class U>
    void destroy(U* p)
    {
        p->~U(); // 原来模板还可以这样用
    }
};

// 5、为什么要对void进行特化?
template<>
class allocator<void>
{
public:
    typedef void value_type;
    typedef void *pointer;
    typedef const void *const_pointer;
    template <class U> struct rebind
    {
        typedef allocator<U> other;
    };
};

3.2 问题解答

1、STL的规范,同时这些type在迭代器和traits技术中有用。

2、摘自MSDN:A structure that enables an allocator for objects of one type to allocate storage for objects of another type.
This structure is useful for allocating memory for type that differs from the element type of the container being implemented.
The member template class defines the type other. Its sole purpose is to provide the type name allocator<_Other>, given the type name allocator<Type>.

For example, given an allocator object al of type A, you can allocate an object of type _Other with the expression:
A::rebind<Other>::other(al).allocate(1, (Other *)0)
Or,

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值