Улучшения для этого распределителя стека C++?
Какие-нибудь предложения для моего стекового распределителя? (За исключением предложений использовать класс с частными / публичными членами)
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 ответа
Вы реализовали стековый распределитель. Вы не можете освободиться, не оставляя пробелов. Обычно пул относится к блоку смежной памяти со слотами фиксированного размера, которые дважды связаны между собой для добавления и удаления в постоянное время.
Вот тот, который вы можете использовать в качестве руководства. Он такой же, как и у вас, но включает в себя базовые итераторы по выделенным узлам и использует шаблоны для распознавания типов.
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 / У вас нет deallocate()
,
2/ A deallocate()
будет очень трудно написать с вашей текущей стратегией, если вы не будете всегда освобождать в точном обратном порядке распределения. Вам нужно будет учесть случай, когда клиент хочет освободить память в середине вашего используемого раздела.
Конечно, если вы делаете освобождение в обратном порядке, (2) не проблема. И если вы вообще никогда не освобождаете память, (1) тоже не проблема.
Это зависит от того, что вы хотите сделать.
Ваша куча не позволяет освобождение. Как вы будете использовать его для объектов, выделенных с новым в C++?