Язык программирования C++ от Страуструпа


..Функции размещения и освобождения - часть 2


Класс Pool предоставляет связанный список элементов требуемого размера. Элементы выделяются из блока памяти фиксированного размера и по мере надобности запрашиваются новые блоки памяти. Элементы группируются большими блоками, чтобы минимизировать число обращений за памятью к функции размещения общего назначения. До тех пор пока не будет уничтожен сам объект PooL, память никогда не возвращается функции размещения общего назначения.

Приведем описание класса Pool:

class Pool {

  struct Link { Link* next; }

  const unsigned esize;

  Link* head;

  Pool(Pool&);            // защита от копирования

  void operator= (Pool&); // защита от копирования

  void grow();

  public:

     Pool(unsigned n);

     ~Pool();

     void* alloc();

     void free(void* b);

};

 

inline void* Pool::alloc()

{

  if (head==0) grow();

  Link* p = head;

  head = p->next;

  return p;

}

 

inline void Pool::free(void* b)

{

  Link* p = (Link*) b;

  p->next = head;

  head = p;

}

Приведенные описания логично поместить в заголовочный файл Pool.h. Следующие определения могут находиться в любом месте программе и завершают наш пример. Объект Pool должен инициализироваться конструктором:

Pool::Pool(unsigned sz) : esize(sz)

{

  head = 0;

}

Функция Pool::grow() будет связывать все элементы в список квантов свободной памяти head, образуя из них новый блок. Определения остальных функций-членов оставлены в качестве упражнений 5 и 6 в $$13.11.

void Pool::grow()

{

  const int overhead = 12;

  const int chunk_size = 8*1024-overhead;

  const int nelem = (chunk_size-esize)/esize;

  char* start = new char[chunk_size];

  char* last = &start[(nelem-1)*esize];

  for (char* p = start; p<last; p+=esize)

     ((Link*)p)->next = ((Link*)p)+1;

  ((Link*)last)->next = 0;

  head = (Link*)start;

}




- Начало -  - Назад -  - Вперед -



Книжный магазин