《STL源碼剖析》筆記(二)空間配置器

#ifndef _JJALLOC_
#define _JJALLOC_
 
#include <new>
#include <cstddef>
#include <cstdlib>
#include <climits>
#include <iostream>
 
namespace JJ
{
    // 使用operator new分配空間
    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);
        }
        return tmp;
    }
    // 使用operator delete回收空間
    template<class T>
    inline void _deallocate(T* buffer)
    {
        ::operator delete(buffer);
    }
    // 在指定內存上構造一個對象
    template<class T1, class T2>
    inline void _construct(T1* p, const T2& value)
    {
        // placement new
        new (p) T1(value);
    }
    // 析構一個對象
    template<class T>
    inline void _destroy(T* ptr)
    {
        ptr->~T();
    }
    // 遵循allocator的標準定義相關結構
    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;
 
        template<class U>
        struct rebind
        {
            typedef allocator<U> other;
        };
 
        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_pointer)&x;
        }
 
        size_type max_size() const
        {
            return size_type(UINT_MAX/sizeof(T));
        }
    };
}
 
#endif

1、T *tmp = (T*)(::operator new((size_t)(size * sizeof(T))));

(T*)強制類型轉換

用::operator new(size)來實現空間的分配,分配size個T大小的空間,並用(size_t)強制類型轉換成size_t大小。

2、set_new_handler(0)

使用set_new_handler可以設置一個函數new_p,當使用new/operator new分配內存失敗時,new_p將被調用。new_p將嘗試使得更多內存空間可用,以使得接下來的內存分配操作能夠成功。如果new_p指向NULL(默認就是NULL),那麼將會拋出bad_alloc異常,這也是爲什麼我們默認使用new失敗的時候將會拋出bad_alloc異常的原因;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章