对基于堆栈的分配器的任何建议? (除了建议使用私人/公共成员的课程)
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;
}
}
答案 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 分配的对象?