Создание кучи по определенному адресу памяти для динамического выделения памяти
Существует ли способ создания кучи в определенном месте памяти (отдельно от системной кучи), которая может использоваться для динамического выделения памяти, но использует динамический распределитель памяти, встроенный в библиотеку C.
Я ищу что-то функционально эквивалентное этому:
UserHeap heap(startAddress, size);
void* allocatedMemory1 = heap.Allocate(100); //Allocate 100 bytes.
void* allocatedMemory2 = heap.Allocate(200); //Allocate 200 bytes.
/* ... Do seomthing useful with the memory ... */
heap.Free(allocatedMemory1);
heap.Free(allocatedMemory2);
Это ухеап.h , кажется, имеет то, что я ищу, но это, кажется, не существует в newlib. Мне интересно, может ли GCC или newlib что-то иметь. Если нет, я думаю, что могу закончить. перенос ptmalloc . Однако, насколько я понимаю, этот код уже находится в библиотеке C, и мне не хотелось бы тратить память на его воспроизведение.
Я использую Sourcery Codebench Lite (GCC) с newlib (библиотекой C).
2 ответа:
Развернуть свой собственный распределитель не так уж сложно и во многих отношениях может быть весьма поучительным. Сначала вам нужно выяснить, какой шаблон распределения / освобождения вы хотите поддерживать в этой куче. Для общего пользования распределители, подобные dlmalloc (Doug Lea), довольно хороши. Существует еще много видов для конкретных применений: основанный на стеке (где свободным всегда является адрес последнего выделенного несвободного блока памяти), основанный на фиксированном размере (где память разделена на фиксированные размеры, которые являются возвращенный), основанный на очереди, малый блок и т. д.
Большинство из них также могут иметь внутренний распределитель, например, предположим, что у вас есть распределитель фиксированного размера, вы можете сказать ему, чтобы он выделял блоки по X байт (из второго распределителя или из системы), которые затем разделяются на блоки по Y байт. Указатели на фрагменты размером Y байт возвращаются, но когда нет свободного блока, вы выделяете новый блок размером X и делите его.
Для удобства можно также реализовать создать / удалить операторы глобально или на определенных классах, чтобы перенаправить их распределения на ваш пользовательский распределитель. Размещение нового в вашей куче также удобно, см. ниже.
Лично я предпочитаю использовать макросы, поскольку они позволяют довольно легко добавлять дополнительную отладочную информацию (функция/строка/etc). ie:
#define CUSTOM_NEW(Heap) new(Heap, __FUNCTION__, __LINE__) int* ptr = CUSTOM_NEW(someHeap) int[32];
Наконец я наткнулся на блог Эли Бендерского, который иллюстрирует именно то, что я искал. memmgr-распределитель памяти с фиксированным пулом