HeapAlloc

Функция HeapAlloc выделяет блок памяти из кучи. Выделенный фрагмент памяти не является перемещаемым.

function HeapAlloc(
  hHeap: THandle;   // дескриптор кучи
  dwFlags: DWORD;   // флаги, управляющие выделением
  dwBytes: DWORD    // количество выделяемых байт
): Pointer; stdcall;

Параметры

hHeap [in]
Указывает кучу, из которой будет выделен фрагмент памяти. Должен быть получен путем вызова одной из функция HeapCreate или GetProcessHeap.

dwFlags [in]
Задает несколько флагов, контролирующих процесс выделения памяти. Задание одого или нескольких таких флагов перекрывает соответствующие значения, которые были заданы при создании кучи при помощи HeapCreate. Этот параметр может быть комбинацией следующих значений:

Флаг Назначение

HEAP_GENERATE_EXCEPTIONS1)

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

HEAP_NO_SERIALIZE1)

Указывает, что пока выполняется текущий вызов HeapAlloc, к куче не будут происходить обращения из других потоков.

Важно! Это значение не может быть указано при обращении к куче процесса. Система может создавать свои собственные потоки без участия приложения, например такие, как обработчик нажатия Ctrl+C, которые могут выполнять доступ к куче процесса.

HEAP_ZERO_MEMORY1)

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

dwBytes [in]
Указывает количество байт, которые должны быть выделены.

Важно! Если куча, указанная параметром hHeap не является "растущей" кучей, значение dwBytes всегда должно быть меньше $7FFF8. Вы можете создать такую кучу путем вызова функции HeapCreate с ненулевым параметром dwMaximumSize.

Возвращаемое значение

При успешном выполнении функция возвращает указатель на выделеный блок.

В случае возникновения ошибки если не указан флаг HEAP_GENERATE_EXCEPTIONS, то возвращаемым значением функции будет nil.

В случае возникновения ошибки если указан флаг HEAP_GENERATE_EXCEPTIONS, то будет сгенерирована одна из следующих исключительных ситуаций: EExternalError (с текстом сообщения "External Exception C000017" (значение $C000017 совпадает с константой STATUS_NO_MEMORY в модуле Windows) либо EAccessViolation.

Примечание: повреждение кучи может привести и к другому исключению, все зависит от характера повреждения кучи.

Важно! В случае возникновения ошибки приложение НЕ ДОЛЖНО производить вызов SetLastError. Приложение также не должно производить вызов GetLastError для получения расширенной информации об ошибке. Это, вероятно, связано с тем, что функции GetLastError и SetLastError сами используют кучу процесса.

Описание

Если функция HeapAlloc выполнилась успешно, то в результате был выделен фрагмент памяти как минимум указанного размера. Но фактически выделенный фрагмент памяти может быть больше запрашиваемого. Приложение может безбоязненно использовать остаток. Для того, чтобы определить действительный размер выделенного фрагмента памяти, необходимо использовать функцию HeapSize.

Для того, чтобы освободить блок памяти, выделенный при помощи функции HeapAlloc, слудет использовать функцию HeapFree. Память, выделяемая при помощи вызова HeapAlloc, не является перемещаемой. Таким образом при работе с кучей не исключается фрагментация памяти.

Защита от повторной входимости гарантирует, что в том случае, когда к куче будет происходить одновременно обращение из двух или нескольких потоков (например, один будет выделять память, а другой будет ее освобождать), работа с кучей будет происходить корректно. Тем не менее защита от повторной входимости требует некоторых затрат рессурсов, поэтому вы должны использовать ее только в том случае, когда несколько потоков одновременно обращаются к куче. Задавая флаг HEAP_NO_SERIALIZE, вы можете отключить защиту от повторной входимости. Одновременное обращение к куче из двух или нескольких потоков, при отключенной защите от повторной входимости, может повлечь за собой разрушение кучи. Поэтому вы должны отключать защиту от посторной входимости только в одном из следующих случаев:

  • В процессе существует только один поток.
  • В процессе существует несколько потоков, но доступ к указанной куче осуществляется только из одного потока.
  • В процессу существует несколько потоков, но приложение обеспечивает свои собственные механизмы защиты от повторной входимости.
  • Примечание: для того, чтобы уберечь себя от ошибки нарушения доступа (access violation), вы должны защитить блоками структурной обработки исключений любой код, выполняющий операции чтения/записи в кучу. Для большей информации по этому вопросу смотрите раздел "Структурная обработка исключений".

    Отличия Windows 95/98
    Менеджер памяти для кучи спроектирован так, что размер одного блока не может превышать четыре мегабайта. Поэтому, если вы рассчитываете оперировать с блоками размером более одного или двух мегабайт, то для этой цели мы рекомендуем пользоваться функциями VirtualAlloc и VirtualAllocEx.

    Требования

    Windows NT/2000: Требуется Windows NT 3.1 или более поздняя версия
    Windows 95/98: Требуется Windows 95 или более поздняя версия
    Бибиотека: Kernel32.dll
    Подключаемый модуль: Windows

    Смотри также:

  • виртуальная память,
  • работа с кучей,
  • описание кучи,
  • список функций для работы с кучей,
  • GetProcessHeap,
  • HeapCreate,
  • HeapDestroy,
  • HeapFree,
  • HeapReAlloc,
  • HeapSize,
  • SetLastError
  • НазадGetProcessHeaps HeapCompactВперед

    © Mystic, 2002