Windows для профессионалов


Использование куч в программах на С++ - часть 2


Она увеличивается на 1 при создании в куче нового объекта CSomeClass и соответственно уменьшается при его уничтожении. Когда счетчик обнуляется, куча освобождается. Для управления кучей в СРР-файл следует включить примерно такой код:

HANDLE CSomeClass::s_hHeap = NULL;
UINT CSomeClass::s_uNumAllocsInHeap = 0;

void* CSomnClass::operator new (size_t size)
{

if (s_hHeap == NULL)
{

// куча не существует, создаем ее
s_hHeap = HeapCreate(HEAP_NO_SERIALIZE, 0, 0);

if (s_hHeap == NULL)

return(NULL);

}

// куча для объектов CSomeClass существует
void* p = HeapAlloc(s hHeap, 0, size);

if (p != NULL)
{

// память выделена успешно; увеличиваем счетчик объектов CSomeClass в куче

s_uNumAllocsInHeap++;

}

// возвращаем адрес созданного объекта CSomeClass
return(p);

}

Заметьте, что сначала я объявил два статических элемента данных, s_hHeap и s_uNumAllocsInHeap, а затем инициализировал их значениями NULL и 0 соответственно.

Оператор new принимает один параметр — size, указывающий число байтов, нужных для хранения CSomeClass Первым делом он создает кучу, если таковой нет. Для проверки анализируется значение переменной s_bHeap: если оно NULL, кучи нет, и тогда она создается функцией HeapCreate, а описатель, возвращаемый функцией, со храняется в переменной s_bHeap, чтобы при следующем вызове оператора new использовать существующую кучу, а не создавать еще одну.

Вызывая HeapCreate, я указал флаг HEAP_NO_SERIALIZE, потому что данная программа построена как однопоточная. Остальные параметры, указанные при вызове HeapCreate, определяют начальный и максимальный размер кучи. Я подставил на их место по нулю. Первый нуль означает, что у кучи нет начального размера, второй — что куча должна расширяться по мере необходимости.

Hе исключено, что Вам показалось, будто параметр size оператора new стоит передать в HeapCreatc как второй параметр. Вроде бы тогда можно инициализировать кучу так, чтобы она была достаточно большой для размещения одного экземпляра класса. И в таком случае функция HeapAlloc при первом вызове работала бы быстрее, так как не пришлось бы изменять размер кучи под экземпляр класса.


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