欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

stl空间配置器demo

程序员文章站 2022-03-23 11:46:43
...

空间配置器实现

最近在看《stl源码剖析》,首先介绍的就是空间配置器

空间配置器allocator,是管理容器的空间(内存或者其他存储空间)用的,基本照抄书上实现了demo如下

/*
 * 1.对于一个空间配置器来说,因为要将分配内存和构造函数步骤分开,
 * 所以至少分为:分配内存、构造、析构、释放内存四步,也就是
 * allocate、construct、destroy、deallocate四个函数
 * 2.标准规定,对一个allocator<T>,和一个类型U,必须有allocator<T>::rebind<U>::other=allocator<U>
 * 这就是rebind函数
 * 3.STL标准规定还需要address、max_size等函数
*/

#include <new>      // for placement new
#include <cstddef>  // for ptrdiff_t, size_t
#include <cstdlib>  // for exit()
#include <climits>  // for UINT_MAX
#include <iostream> // for cerr
#include <vector>

#define __MYSTL_BEGIN_NAMESPACE namespace mystl {
#define __MYSTL_END_NAMESPACE }

__MYSTL_BEGIN_NAMESPACE

template <class T>
inline T* _allocate(ptrdiff_t size, T*) {
    std::set_new_handler(0);
    T *tmp = (T*)(::operator new((size_t)(size * sizeof(T))));
    if (tmp == 0) {
        std::cerr << "out of memory" << std::endl;
        exit(1);
    }
    std::cout << "in my _allocate" << std::endl;

    return tmp;
}

template <class T>
inline void _deallocate(T *buffer) {
    std::cout << "in my _deallocate" << std::endl;
    ::operator delete(buffer);
}

template <class T1, class T2>
inline void _construct(T1 *p, const T2 &value) {
    std::cout << "in my _construct" << std::endl;
    new(p) T1(value); // placement new
}

template <class T>
inline void _destroy(T *ptr) {
    std::cout << "in my _destroy" << std::endl;
    ptr->~T();
}

template <class T>
class allocator {
public:
    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;
    typedef ptrdiff_t difference_type;

    // rebind allocator of type U
    template <class U>
    struct rebind {
        typedef allocator<U> other;
    };

    // hint used for locality.
    pointer allocate(size_type n, const void *hint = 0) {
        return _allocate((difference_type)n, (pointer)0);
    }

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

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

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

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

    const_pointer const_address(const_reference x) {
        return (const_reference)&x;
    }

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

__MYSTL_END_NAMESPACE

int main() {
    int ia[5] = {0, 1, 2, 3, 4};

    std::vector<int , mystl::allocator<int> > iv(ia, ia + 5);
    for (unsigned int i = 0; i < iv.size(); ++i) {
        std::cout << iv[i] << ' ';
    }
    std::cout << std::endl;

    return 0;
}

注:在g++ 4.8.5环境下编译通过,vs2010不知为什么没编译通过

运行结果:

可见,这里只进行了一次内存分配,而进行了5次构造、析构

in my _allocate
in my _construct
in my _construct
in my _construct
in my _construct
in my _construct
0 1 2 3 4 
in my _destroy
in my _destroy
in my _destroy
in my _destroy
in my _destroy
in my _deallocate