Операционная система Microsoft Windows 3.1 для программиста -том 3

Работа с удаляемыми блоками памяти


Для того чтобы заказать удаляемый блок памяти, вы должны указать флаги GMEM_DISCARDABLE и GMEM_MOVEABLE , например:

hmemGlDiscard = GlobalAlloc(GMEM_MOVEABLE | GMEM_DISCARDABLE, 200000l);

При необходимости Windows может удалить полученный таким образом блок из памяти, сохранив только его идентификатор, и использовать ранее распределенную этому блоку памяти для других приложений.

При попытке зафиксировать удаленный блок с помощью функции GlobalLock приложение получит от этой функции значение NULL. В этом случае следует вызвать функцию GlobalFlags , предназначенную для определения состояния блока памяти, и проверить, находится ли данный блок в удаленном состоянии.

Приведем прототип функции GlobalFlags:

UINT WINAPI GlobalFlags(HGLOBAL hglb);

Функция возвращает состояние блока памяти, указанного своим единственным параметром. Младший байт возвращаемого значения содержит содержимое счетчика фиксаций блока памяти. В старшем байте могут быть установлены флаги GMEM_DISCARDABLE и GMEM_DISCARDED.

Если установлен флаг GMEM_DISCARDABLE, проверяемый блок памяти может быть удален Windows в процессе дефрагментации свободной области памяти. Если же установлен флаг GMEM_DISCARDED, удаление блока памяти уже произошло.

Для получения доступа к удаленному блоку памяти его необходимо восстановить, вызвав функцию GlobalReAlloc. Эта функция позволяет изменить характеристики существующего блока памяти.

Приведем прототип функции GlobalReAlloc :

HGLOBAL WINAPI GlobalReAlloc(HGLOBAL hglb, DWORD cbNewSize, UINT fuAlloc);

Параметр hglb указывает идентификатор восстанавливаемого блока памяти.

При помощи параметра cbNewSize вы должны указать размер блока памяти, причем можно восстановить удаленный блок памяти и изменить его размер одновременно.



Параметр fuAlloc определяет тип восстановленного блока памяти. Можно указывать логическую комбинацию следующих флагов:

Флаг Описание
GMEM_DISCARDABLE Если блок памяти был перемещаемый, то теперь дополнительно он будет и удаляемый. Этот флаг должен использоваться совместно с флагом GMEM_MODIFY
GMEM_MODIFY Выполняется изменение характеристик существующего блока памяти. этот флаг необходимо указывать вместе с флагами GMEM_DISCARDABLE и GMEM_MOVEABLE
GMEM_MOVEABLE Если раньше указанный блок памяти был перемещаемым и удаляемым, содержимое счетчика фиксирования для него равно нулю и новый размер блока указан равным нулю, данный блок будет удален. Если же параметр cbNewSize равен нулю, но блок памяти не является перемещаемым или удаляемым, функция вернет признак ошибки.Для фиксированного блока памяти ненулевой длины данный флаг разрешает перемещение, т. е. преобразует фиксированный блок в перемещаемый.
GMEM_NODISCARD Блок памяти не может быть удален операционной системой. Этот флаг должен использоваться совместно с флагом GMEM_MODIFY
GMEM_ZEROINIT Если размер блока памяти увеличивается, во все байты дополнительной памяти необходимо записать нулевые значения. Этот флаг несовместим с флагом GMEM_MODIFY

Восстановив блок памяти, вы должны зафиксировать его функцией GlobalLock и затем восстановить прежнее содержимое, так как после удаления от блока остался только идентификатор.



Содержание раздела