首页 > 代码库 > STL初探——设计一个简单的空间配置器

STL初探——设计一个简单的空间配置器

  

#pragma once
#ifndef _M_ALLOCATOR
#define _M_ALLOCATOR
#include <new>            //用于定向开辟内存
#include <cstddef>        //用于存储中间量的类型,ptrdiff_t和size_t
#include <cstdlib>        //exit()
#include <climits>        //UINT_MAX
#include <iostream>       //cerr
namespace m_allocator 
{
    template<class T>
    inline T* _m_allocate(ptrdiff_t size, T*)   //ptrdiff_t, 两个指针距离,个人你认为是long int类型
    {
        set_new_handler(0);                     //set_new_handler(0)主要是为了卸载目前的内存分配异常处理函数
                                                //这样一旦分配内存失败的话,C++就会强制性抛出std:bad_alloc异常,而不是跑到处理某个异常处理函数去处理
        T* temp = (T*)(::operator new((size_t)(size* sizeof(T*))));
        if (temp == 0)
        {
            cerr << "out of memory" << endl;
            exit(1);
        }
        return temp;
    }

//释放内存
template<class T>
inline void _m_deallocate(T* buffer) 
{
    ::operator delete (buffer);
}


//开辟空间,构造对象
template<class T1, class T2>
inline void _m_construct(T1* p, const T2& value)
{
    new(p) T1(value);
}

//析构函数
template<class T>
inline void _m_destory(T* ptr)
{
    ptr->~T();
}

template<class T>
class _m_alloctor
{
public:
    typedef T                value_type;
    typedef T*                pointer;
    typedef const T*        const_pointer;
    typedef T&                referance;
    typedef const T&        const_referance;
    typedef size_t            size_type;
    typedef ptrdiff_t        difference_type;

    template<class U>
    struct m_rebind
    {
        typedef _m_alloctor<U> other;
    };

    pointer allocate(size_type n, const void* hint = 0) 
    {
        return _m_allocate((difference_type)n, (pointer)0);
    }

    void deallocate(pointer p, size_type n) 
    {
        _m_deallocate(p);
    }

    void construct(pointer p, const T& value)
    {
        _m_construct(p, value);
    }

    void destroy(pointer p)
    {
        _m_destory(p);
    }

    pointer address(referance x)
    {
        return pointer(&x);
    }

    const_pointer address(const_referance x)
    {
        return const_pointer(&x);
    }

    size_type max_size() const
    {
        return size_type(UINT_MAX / sizeof(T));
    }
};

}
#endif // !_M_ALLOCATOR
#include "m_allocator.h"
#include <vector>
#include <iostream>
using namespace std;

int main()
{
    int ia[5] = {0,1,2,3,4};
    unsigned int i = 0;
    vector<int, m_allocator::_m_alloctor<int> > iv(ia,ia + 5);

    for (auto i = iv.begin(); i != iv.end(); i++)
    {
        printf("%d", *i);
    }
    printf("%s", "\n");
    return 0;
}

  将以上空间配置器 m_allocator::_m_alloctor应用于程序中,只能有限度搭配PJ STL 和RW STL(两种不同版本STL源码),因为PJ STL未完全遵循STL规格,其所供应的许多容器都需要一个非标准的空间配置器接口allocator::_Charalloc(), 而RW STL在很多容器身上运用了缓冲区,情况更复杂,m_allocator

::_m_alloctor无法与之兼容,至于完全无法应用于SGI STL, 是因为SGI STL在这个项目上用上了自己所定义的一套标准,并没有太多遵循STL标准规格。

  事实上SGI STL仍然提供了一个标准的配置器接口simple_alloc,只是把它做了一层隐藏, 且缺省的空间配置器并不是该接口而已。

STL初探——设计一个简单的空间配置器