自定义内存分配器示例(需要一些说明)

时间:2017-04-01 01:03:30

标签: c++ memory-management

刚刚运行这个自定义内存分配器头文件的示例,我只是想更好地理解一些编写的代码。

class Allocator
{
public:
    Allocator(size_t size, void* start)
    {
        _start          = start;
        _size           = size;

        _used_memory     = 0;
        _num_allocations = 0;
    }

    virtual ~Allocator()
    {
        ASSERT(_num_allocations == 0 && _used_memory == 0);

        _start = nullptr;
        _size   = 0;
    }

    virtual void* allocate(size_t size, u8 alignment = 4) = 0;

    virtual void deallocate(void* p) = 0;

    void* getStart() const
    {
        return _start;
    }

    size_t getSize() const
    {
        return _size;
    }

    size_t getUsedMemory() const
    {
        return _used_memory;
    }

    size_t getNumAllocations() const
    {
        return _num_allocations;
    }

protected:
    void*         _start;
    size_t        _size;

    size_t        _used_memory;
    size_t        _num_allocations;
};

namespace allocator
{
    template <class T> T* allocateNew(Allocator& allocator)
    {
        return new (allocator.allocate(sizeof(T), __alignof(T))) T;
    }

    template <class T> T* allocateNew(Allocator& allocator, const T& t)
    {
        return new (allocator.allocate(sizeof(T), __alignof(T))) T(t);
    }

    template<class T> void deallocateDelete(Allocator& allocator, T& object)
    {
        object.~T();
        allocator.deallocate(&object);
    }

    template<class T> T* allocateArray(Allocator& allocator, size_t length)
    {
        ASSERT(length != 0);

        u8 headerSize = sizeof(size_t)/sizeof(T);

        if(sizeof(size_t)%sizeof(T) > 0)
            headerSize += 1;

        //Allocate extra space to store array length in the bytes before the array
        T* p = ( (T*) allocator.allocate(sizeof(T)*(length + headerSize), __alignof(T)) ) + headerSize;

        *( ((size_t*)p) - 1 ) = length;

        for(size_t i = 0; i < length; i++)
            new (&p[i]) T;

        return p;
    }

    template<class T> void deallocateArray(Allocator& allocator, T* array)
    {
        ASSERT(array != nullptr);

        size_t length = *( ((size_t*)array) - 1 );

        for(size_t i = 0; i < length; i++)
            array[i].~T();

        //Calculate how much extra memory was allocated to store the length before the array
        u8 headerSize = sizeof(size_t)/sizeof(T);

        if(sizeof(size_t)%sizeof(T) > 0)
            headerSize += 1;

        allocator.deallocate(array - headerSize);
    }
};
  1. 为什么需要/使用启动参数?如果我想分配一些空间,我只需要指定需要分配多少内存?

  2. 如果我想创建一个简单的线性自定义内存分配器,我还需要包含前两个模板吗?

  3. 对于此代码段new (&p[i]) T;,为什么最后是模板类型名称?

  4. 谢谢!

1 个答案:

答案 0 :(得分:1)

1)开始将指针存储到&#34;真的&#34;分配的内存由此分配器分配,稍后需要传递给相应的自由函数。

2)我认为从头开始编写分配器会更好

3)此表达式是一个放置新的运算符调用,而&amp; p [i]是一个将构造类型为T的对象的地址