这个C ++堆栈分配器的改进?

时间:2009-04-21 07:33:23

标签: c++ memory memory-management

对基于堆栈的分配器的任何建议? (除了建议使用私人/公共成员的课程)

struct Heap
{
    void* heap_start;
    void* heap_end;
    size_t max_end;

    Heap(size_t size)
    {
        heap_start = malloc(size);
        heap_end = heap_start;
        max_end = size + (size_t) heap_start;
    }

    ~Heap()
    {
        ::free(heap_start);
    }

    void* allocate(size_t bytes)
    {

        size_t new_end = ((size_t) heap_end) + bytes;

        if( new_end > max_end )
            throw std::bad_alloc();

        void* output = heap_end;
        heap_end = (void*) new_end;
        return output;
    }

}

4 个答案:

答案 0 :(得分:4)

size_t new_end = ((size_t) heap_end) + bytes;

不好,永远不要做那样的事情,你假设sizeof(size_t)== sizeof(void *),如果bytes==(size_t)(-1)这不起作用会发生什么

此外,您需要确保返回的指针已对齐。 否则你会遇到问题。因此,您需要根据您的平台确保字节数为4或8的倍数。

class {...
char *max_end,*head_end,*heap_start;
};

...
max_end=heap_start+size;
...
bytes=align_to_platform_specific_value(bytes);
if(max_end-heap_end >= bytes) {
   void* output = (void*)heap_end;
   heap_end+=bytes;
   return output;
}
throw std::bad_alloc();

建议?不要重新发明轮子。有很多很好的池库。

答案 1 :(得分:4)

您已经实现了基于堆栈的分配器。你不能在没有留下空白的情况下自由活动通常,池是指具有固定大小的插槽的连续内存块,它们是双向链接以允许恒定时间添加和删除。

Here's one您可以将其用作指南。它与您的行相同,但包括基于已分配节点的基本迭代器,并使用模板进行类型识别。

答案 2 :(得分:2)

两个明显的问题:

1 /您没有deallocate()

2 / A deallocate()将很难用您当前的策略编写,除非您总是按照与分配完全相反的顺序解除分配。您需要满足客户想要在您使用的部分中间释放内存的情况。

当然,如果你以相反的顺序解除分配,(2)不是问题。如果你从来没有释放过记忆,(1)也不是问题。

这取决于你想要它做什么。

答案 3 :(得分:1)

您的堆不允许重新分配。如何将它用于在C ++中用 new 分配的对象?