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 o 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 de heap (RtlAllocateHeap e RtlFreeHeap).

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

Esse parâmetro pode ser um ou mais 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 é growable. 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 ao 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 Resultado
ReserveSize zero, CommitSize zero Inicialmente, são reservadas 64 páginas para o heap. Uma página é inicialmente confirmada.
ReserveSize zero, CommitSize nonzero RtlCreateHeap define ReserveSize ser igual a CommitSizee arredonda ReserveSize até o múltiplo mais próximo de (PAGE_SIZE * 16).
ReserveSize nonzero, 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 de HEAP_NO_SERIALIZE estiver definido, esse parâmetro deverá ser NULL.

[in, optional] Parameters

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

Valor de retorno

RtlCreateHeap retorna um identificador a ser usado no acesso ao heap criado.

Observações

RtlCreateHeap cria um objeto de heap privado do qual o processo de chamada pode alocar blocos de memória chamando RtlAllocateHeap. O tamanho de confirmação inicial determina o número de páginas que são inicialmente alocadas para o heap. O tamanho da reserva inicial determina o número de páginas que são inicialmente reservadas para o heap. 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 exceder 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 acessí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 RtlAllocateHeap exceder 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 acessível, ocorrerá 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 virtualMemoryThreshold membro da estrutura parâmetros , o que for menor. O heap também pode precisar conter o tamanho da solicitação para fins de metadados e alinhamento, portanto, as solicitações para alocar blocos em 4096 Bytes (1 Página) do VirtualMemoryThreshold podem 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 Parâmetros para RtlCreateHeap.)

Se o heap for growable, 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 apenas 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 do 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.

A configuração 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 de exclusão mútua para um heap específico.

Nota

Para se proteger contra uma violação de acesso, use o tratamento de exceção estruturado para proteger qualquer código que grava ou lê 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
de cliente com suporte mínimo Windows XP
da Plataforma de Destino Universal
cabeçalho ntifs.h (inclua Ntifs.h)
biblioteca Ntoskrnl.lib
de DLL NtosKrnl.exe (modo kernel); Ntdll.dll (modo de usuário)
IRQL < DISPATCH_LEVEL

Consulte também

rtlAllocateHeap

RtlDestroyHeap

rtlFreeHeap