Compartilhar via


Função RtlCreateHeap (ntifs.h)

A rotina RtlCreateHeap cria um objeto heap que pode ser usado pelo processo de chamada. Essa rotina reserva espaço no espaço de endereço virtual do processo e aloca armazenamento físico para uma parte inicial especificada desse bloco.

Sintaxe

NTSYSAPI PVOID RtlCreateHeap(
  [in]           ULONG                Flags,
  [in, optional] PVOID                HeapBase,
  [in, optional] SIZE_T               ReserveSize,
  [in, optional] SIZE_T               CommitSize,
  [in, optional] PVOID                Lock,
  [in, optional] PRTL_HEAP_PARAMETERS Parameters
);

Parâmetros

[in] Flags

Sinalizadores que especificam atributos opcionais do heap. Essas opções afetam o acesso subsequente ao novo heap por meio de chamadas para as funções heap (RtlAllocateHeap e RtlFreeHeap).

Os chamadores devem definir esse parâmetro como zero se nenhum atributo opcional for solicitado.

Esse parâmetro pode usar um dos valores a seguir.

Valor Significado
HEAP_GENERATE_EXCEPTIONS Especifica que o sistema indicará uma falha de heap gerando uma exceção, como STATUS_NO_MEMORY, em vez de retornar NULL.
HEAP_GROWABLE Especifica que o heap pode ser ampliado. Deve ser especificado se HeapBase for NULL.
HEAP_NO_SERIALIZE Especifica que a exclusão mútua não será usada quando as funções de heap alocarem e liberarem memória desse heap. O padrão, quando HEAP_NO_SERIALIZE não é especificado, é serializar o acesso ao heap. A serialização do acesso de heap permite que dois ou mais threads aloquem simultaneamente e liberem memória do mesmo heap.

[in, optional] HeapBase

Especifica uma das duas ações:

Se HeapBase for um valor não NULL, ele especificará o endereço base para um bloco de memória alocada pelo chamador a ser usado para o heap.

Se HeapBase for NULL, RtlCreateHeap alocará memória do sistema para o heap do espaço de endereço virtual do processo.

[in, optional] ReserveSize

Se ReserveSize for um valor diferente de zero, ele especificará a quantidade inicial de memória, em bytes, a ser reservada para o heap. RtlCreateHeap arredonda ReserveSize até o limite da próxima página e reserva um bloco desse tamanho para o heap.

Esse parâmetro é opcional e pode ser zero. A tabela a seguir resume a interação dos parâmetros ReserveSize e CommitSize .

Valores Result
ReserveSize zero, CommitSize zero 64 páginas são inicialmente reservadas para o heap. Uma página é inicialmente confirmada.
ReserveSize zero, CommitSize nonzero RtlCreateHeap define ReserveSize como igual a CommitSize e arredonda ReserveSize para cima até o múltiplo mais próximo de (PAGE_SIZE * 16).
ReserveSize diferente de zero, CommitSize zero Uma página é inicialmente confirmada para o heap.
ReserveSize nonzero, CommitSize nonzero Se CommitSize for maior que ReserveSize, RtlCreateHeap reduzirá CommitSize para ReserveSize.

[in, optional] CommitSize

Se CommitSize for um valor diferente de zero, ele especificará a quantidade inicial de memória, em bytes, para confirmar para o heap. RtlCreateHeap arredonda CommitSize até o limite da próxima página e confirma um bloco desse tamanho no espaço de endereço virtual do processo para o heap.

Esse parâmetro é opcional e pode ser zero.

[in, optional] Lock

Ponteiro para uma estrutura ERESOURCE opaca a ser usada como um bloqueio de recurso. Esse parâmetro é opcional e pode ser NULL. Quando fornecida pelo chamador, a estrutura deve ser alocada do pool nãopagado e inicializada chamando ExInitializeResourceLite ou ExReinitializeResourceLite. Se o sinalizador HEAP_NO_SERIALIZE estiver definido, esse parâmetro deverá ser NULL.

[in, optional] Parameters

Ponteiro para uma estrutura RTL_HEAP_PARAMETERS que contém parâmetros a serem aplicados ao criar o heap. Esse parâmetro é opcional e pode ser NULL.

Retornar valor

RtlCreateHeap retorna um identificador a ser usado para acessar o heap criado.

Comentários

RtlCreateHeap cria um objeto de heap privado do qual o processo de chamada pode alocar blocos de memória chamando RtlAllocateHeap. O tamanho inicial da confirmação determina o número de páginas inicialmente alocadas para o heap. O tamanho inicial da reserva determina o número de páginas inicialmente reservadas para o heap. As páginas reservadas, mas não confirmadas, criam um bloco no espaço de endereço virtual do processo no qual o heap pode se expandir.

Se as solicitações de alocação feitas por RtlAllocateHeap excederem o tamanho de confirmação inicial do heap, o sistema confirmará páginas adicionais de armazenamento físico para o heap, até o tamanho máximo do heap. Se o heap não for navegável, seu tamanho máximo será limitado ao seu tamanho de reserva inicial.

Se o heap for growable, seu tamanho será limitado apenas pela memória disponível. Se as solicitações de RtlAllocateHeap excederem o tamanho atual das páginas confirmadas, o sistema chamará ZwAllocateVirtualMemory para obter a memória necessária, supondo que o armazenamento físico esteja disponível.

Além disso, se o heap não for navegável, surgirá uma limitação absoluta: o tamanho máximo de um bloco de memória no heap será 0x7F000 bytes. O limite de memória virtual do heap é igual ao tamanho máximo do bloco de heap ou ao valor do membro VirtualMemoryThreshold da estrutura Parameters , o que for menor. O heap também pode precisar preencher o tamanho da solicitação para fins de metadados e alinhamento para que as solicitações para alocar blocos dentro de 4096 Bytes (1 Página) do VirtualMemoryThreshold possam falhar mesmo que o tamanho máximo do heap seja grande o suficiente para conter o bloco. (Para obter mais informações sobre VirtualMemoryThreshold, consulte os membros do parâmetro Parameters para RtlCreateHeap.)

Se o heap for executável, as solicitações para alocar blocos maiores que o limite de memória virtual do heap não falharão automaticamente; o sistema chama ZwAllocateVirtualMemory para obter a memória necessária para esses blocos grandes.

A memória de um objeto de heap privado é acessível somente ao processo que o criou.

O sistema usa memória do heap privado para armazenar estruturas de suporte de heap, portanto, nem todo o tamanho de heap especificado está disponível para o processo. Por exemplo, se RtlAllocateHeap solicitar 64 quilobytes (K) de um heap com um tamanho máximo de 64K, a solicitação poderá falhar devido à sobrecarga do sistema.

Se HEAP_NO_SERIALIZE não for especificado (o padrão simples), o heap serializará o acesso dentro do processo de chamada. A serialização garante a exclusão mútua quando dois ou mais threads tentam alocar simultaneamente ou liberar blocos do mesmo heap. Há um pequeno custo de desempenho para serialização, mas ele deve ser usado sempre que vários threads alocam e liberam memória do mesmo heap.

Definir HEAP_NO_SERIALIZE elimina a exclusão mútua no heap. Sem serialização, dois ou mais threads que usam o mesmo identificador de heap podem tentar alocar ou liberar memória simultaneamente, provavelmente causando corrupção no heap. Portanto, HEAP_NO_SERIALIZE só podem ser usados com segurança nas seguintes situações:

  • O processo tem apenas um thread.

  • O processo tem vários threads, mas apenas um thread chama as funções de heap para um heap específico.

  • O processo tem vários threads e o aplicativo fornece seu próprio mecanismo para exclusão mútua para um heap específico.

Observação

Para se proteger contra uma violação de acesso, use o tratamento de exceção estruturado para proteger qualquer código que grave ou leia de um heap. Para obter mais informações sobre o tratamento de exceções estruturadas com acessos de memória, consulte Tratamento de exceções**.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows XP
Plataforma de Destino Universal
Cabeçalho ntifs.h (inclua Ntifs.h)
Biblioteca Ntoskrnl.lib
DLL NtosKrnl.exe (modo kernel); Ntdll.dll (modo de usuário)
IRQL < DISPATCH_LEVEL

Confira também

RtlAllocateHeap

RtlDestroyHeap

RtlFreeHeap