Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
шпора 97.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
778.75 Кб
Скачать

7.2 Управление памятью кучи

Выделение блоков памяти из кучи осуществляется путем указания дескриптора ку­чи, размера блока и нескольких флагов.

LPVOID HeapAlloc ( HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)

Возвращаемое значение: указатель на выделенный блок памяти или NULL при неудаче (кроме случаев,- когда задано генерирование исключений).

Параметры функции HeapAlloc

hHeap — дескриптор кучи, из которой должен быть выделен блок памяти. Этот де­скриптор должен быть получен функциями GetProcessHeap или HeapCreate.

dwFlags представляет собой комбинацию трех флагов.

• HEAP_GENERATE_EXCEPTIONS И HEAP_NO_SERIALIZE имеют то же значение, что и для функции HeapCreate. Первый флаг можно не указывать, если он был установлен функцией HeapCreate для данной кучи. Второй флаг используется при выделении памяти из кучи процесса.

• HEAP_ZERO_MEMORY указывает на то, что выделенная память будет заполнена нулями; в противном случае содержимое памяти будет неопределенным.

dwBytes — размер блока памяти, который должен быть выделен. Для невозрастаю­щих куч его предел составляет 0x7FFF8 (примерно 0,5 Мбайт).

Освобождение памяти из кучи выполняется элементарно.

BOOL HeapFree ( HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)

dwFlags должен быть равен нулю или константе HEAP_NO_SERIALIZE.

lpMem должен иметь значение, возвращенное функцией HeapAlloc или HeapReAlloc,

а hHeap — это, конечно, дескриптор кучи, из которой был выделен блок lpMem.

Для изменения размера блоки памяти могут быть выделены заново.

LPVOID HeapReAlloc ( HANDLE hHeap, DWORD dwFlags,

LPVOID lpMem, SIZE_T dwBytes)

Возвращаемое значение: указатель на выделенный заново блок. При неудаче возвращает NULL или вызывает исключение.

Параметры функции HeapReAlloc

Первый параметр hHeap упоминался выше. dwFlags указывает некоторые важные управляющие флаги.

• HEAP_GENERATE_EXCEPTIONS и HEAP_NO_SERIAL_S1ZE, как в предыдущих случаях.

• HEAP_ZERO_MEMORY — инициализируется только заново выделяемая память (когда значение dwByte больше размера исходного блока). Содержимое исход­ного блока не изменяется.

• HEAP_REALLOC_IN_PLACE_ONLY указывает на то, что блок не может быть пере­мешен. При увеличении размера блока память должна выделяться по адресу, следующему сразу после существующего блока.

lpMem указывает на существующий блок в куче hHeap, который должен быть вы­делен заново.

dwBytes — новый размер блока, который может быть больше или меньше текущего.

Обычно возвращаемый указатель — тот же, что и значение lpMem. Если же блок был перемещен (это разрешается, когда флаг HEAP_REALLOC_IN_PLACE_ONLY опущен), то воз­вращенное значение будет другим. Следите за обновлением всех ссылок на блок.

Размер выделенного блока определяется функцией НеарSize (на самом деле имя этой функции должно быть BlockSize, так как она относится к блоку, а не к куче) с указанием дескриптора кучи и указателя на блок.

DWORD HeapSize ( HANDLE hHeap, DWORD dwFlags,

LPCVOID lpMem)

Возвращаемое значение:.размер блока или нуль при неудаче.

Флаг HEAP_NO_SER IALIZE

В функциях HeapCreate, HeapAlloc и HeapReAlloc может быть указан флаг HEAP_NO_SERIALIZE. Его применение позволяет получить небольшой прирост быст­родействия, производительности, так как функции не предоставляют потокам взаим­ные исключения при доступе к куче. Применение этого флага безопасно в немногих описанных ниже ситуациях.

• Программа не использует потоки, или, точнее, процесс имеет только один поток.

• Каждый поток имеет собственную кучу или группу куч, к которым не обраща­ются другие потоки.

• Программа имеет собственный механизм взаимных исключений для предотвращения одновременного доступа к куче нескольких потоков, исполь­зующих функции HeapAlloc и HeapReAlloc. Для тех же целей в Windows 2000/NT доступны функции HeapLock и HeapUnlock.

Флаг HEAP_GENERATE__EXCEPTIONS

Вызов исключений в случае неудачного выделения памяти делает ненужными раз­дражающие проверки ошибок после каждого выделения. Более того, исключение или обработчик завершения может очистить память, которая была выделена. Возможны два кода исключения.

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

2. STATUS_ACCESS_VIOLATION указывает на то, что куча была повреждена. На­пример, программа могла произвести запись в память за границами выделен­ного блока.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]