Partager via


RtlCreateHeap, fonction (ntifs.h)

La routine RtlCreateHeap crée un objet tas qui peut être utilisé par le processus appelant. Cette routine réserve de l’espace d’adressage virtuel du processus et alloue un stockage physique pour une partie initiale spécifiée de ce bloc.

Syntaxe

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
);

Paramètres

[in] Flags

Indicateurs spécifiant des attributs facultatifs du tas. Ces options affectent l’accès ultérieur au nouveau tas via des appels aux fonctions de tas (RtlAllocateHeap et RtlFreeHeap).

Les appelants doivent définir ce paramètre sur zéro si aucun attribut facultatif n’est demandé.

Ce paramètre peut être une ou plusieurs des valeurs suivantes.

Valeur Signification
HEAP_GENERATE_EXCEPTIONS Spécifie que le système indiquera une défaillance de tas en générant une exception, telle que STATUS_NO_MEMORY, au lieu de retourner NULL.
HEAP_GROWABLE Spécifie que le tas est extensible. Doit être spécifié si heapBase a la valeur NULL.
HEAP_NO_SERIALIZE Spécifie que l’exclusion mutuelle ne sera pas utilisée lorsque les fonctions de tas allouent et libèrent de la mémoire de ce tas. La valeur par défaut, lorsque HEAP_NO_SERIALIZE n’est pas spécifiée, consiste à sérialiser l’accès au tas. La sérialisation de l’accès au tas permet à deux threads ou plus d’allouer et de libérer de la mémoire à partir du même tas.

[in, optional] HeapBase

Spécifie l’une des deux actions suivantes :

Si HeapBase est une valeur non NULL, elle spécifie l’adresse de base d’un bloc de mémoire allouée à l’appelant à utiliser pour le tas.

Si heapBase a la valeur NULL, RtlCreateHeap alloue la mémoire système pour le tas à partir de l’espace d’adressage virtuel du processus.

[in, optional] ReserveSize

Si ReserveSize est une valeur différente de zéro, elle spécifie la quantité initiale de mémoire, en octets, à réserver pour le tas. RtlCreateHeap arrondit ReserveSize jusqu’à la limite de page suivante, puis réserve un bloc de cette taille pour le tas.

Ce paramètre est facultatif et peut être égal à zéro. Le tableau suivant résume l’interaction des paramètres ReserveSize et CommitSize.

Valeurs Résultat
ReserveSize zéro, CommitSize zéro 64 pages sont initialement réservées au tas. Une page est initialement validée.
ReserveSize zéro, CommitSize non zéro RtlCreateHeap définit ReserveSize être égal à CommitSize, puis arrondit ReserveSize jusqu’au multiple le plus proche de (PAGE_SIZE * 16).
ReserveSize non zéro, CommitSize zéro Une page est initialement validée pour le tas.
ReserveSize non zéro, CommitSize non zéro Si CommitSize est supérieur à ReserveSize, RtlCreateHeap réduit CommitSize à ReserveSize.

[in, optional] CommitSize

Si CommitSize est une valeur différente de zéro, elle spécifie la quantité initiale de mémoire, en octets, à valider pour le tas. RtlCreateHeap arrondit CommitSize jusqu’à la limite de page suivante, puis valide un bloc de cette taille dans l’espace d’adressage virtuel du processus pour le tas.

Ce paramètre est facultatif et peut être égal à zéro.

[in, optional] Lock

Pointeur vers une structure ERESOURCE opaque à utiliser comme verrou de ressource. Ce paramètre est facultatif et peut être NULL. Lorsqu’elle est fournie par l’appelant, la structure doit être allouée à partir d’un pool non paginé et initialisée en appelant ExInitializeResourceLite ou ExReinitializeResourceLite. Si l’indicateur HEAP_NO_SERIALIZE est défini, ce paramètre doit être NULL.

[in, optional] Parameters

Pointeur vers une structure RTL_HEAP_PARAMETERS qui contient des paramètres à appliquer lors de la création du tas. Ce paramètre est facultatif et peut être NULL.

Valeur de retour

RtlCreateHeap retourne un handle à utiliser pour accéder au tas créé.

Remarques

RtlCreateHeap crée un objet de tas privé à partir duquel le processus appelant peut allouer des blocs de mémoire en appelant RtlAllocateHeap. La taille de validation initiale détermine le nombre de pages qui sont initialement allouées pour le tas. La taille de réserve initiale détermine le nombre de pages initialement réservées au tas. Les pages réservées mais non validées créent un bloc dans l’espace d’adressage virtuel du processus dans lequel le tas peut se développer.

Si les demandes d’allocation effectuées par RtlAllocateHeap dépassent la taille de validation initiale du tas, le système valide des pages supplémentaires de stockage physique pour le tas, jusqu’à la taille maximale du tas. Si le tas n’est pasrowable, sa taille maximale est limitée à sa taille de réserve initiale.

Si le tas est extensible, sa taille est limitée uniquement par la mémoire disponible. Si les demandes par RtlAllocateHeap dépassent la taille actuelle des pages validées, le système appelle ZwAllocateVirtualMemory pour obtenir la mémoire nécessaire, en supposant que le stockage physique est disponible.

En outre, si le tas n’est pas extensible, une limitation absolue survient : la taille maximale d’un bloc de mémoire dans le tas est 0x7F000 octets. Le seuil de mémoire virtuelle du tas est égal à la taille maximale du bloc de tas ou à la valeur du membre VirtualMemoryThreshold de la structure parameters , selon ce qui est inférieur. Le tas peut également avoir besoin de remplir la taille de la requête à des fins de métadonnées et d’alignement afin que les demandes d’allocation de blocs dans 4096 octets (1 page) de la VirtualMemoryThreshold peuvent échouer même si la taille maximale du tas est suffisamment grande pour contenir le bloc. (Pour plus d’informations sur VirtualMemoryThreshold, consultez les membres du paramètre Parameters pour RtlCreateHeap.)

Si le tas est extensible, les demandes d’allocation de blocs supérieurs au seuil de mémoire virtuelle du tas ne échouent pas automatiquement ; le système appelle ZwAllocateVirtualMemory pour obtenir la mémoire nécessaire pour ces blocs volumineux.

La mémoire d’un objet tas privé est accessible uniquement au processus qui l’a créé.

Le système utilise la mémoire du tas privé pour stocker les structures de prise en charge du tas, de sorte que la taille du tas spécifiée n’est pas disponible pour le processus. Par exemple, si RtlAllocateHeap demande 64 kilo-octets (K) à partir d’un tas dont la taille maximale est de 64 Ko, la requête peut échouer en raison de la surcharge système.

Si HEAP_NO_SERIALIZE n’est pas spécifié (valeur par défaut simple), le tas sérialise l’accès au sein du processus appelant. La sérialisation garantit l’exclusion mutuelle lorsque deux threads ou plus tentent d’allouer ou de libérer simultanément des blocs à partir du même tas. Il existe un coût de performances réduit pour la sérialisation, mais il doit être utilisé chaque fois que plusieurs threads allouent et libèrent de la mémoire à partir du même tas.

Définir HEAP_NO_SERIALIZE élimine l’exclusion mutuelle sur le tas. Sans sérialisation, deux threads ou plus qui utilisent le même handle de tas peuvent tenter d’allouer ou de libérer de la mémoire simultanément, ce qui entraîne probablement une altération dans le tas. Par conséquent, HEAP_NO_SERIALIZE ne peut être utilisé en toute sécurité que dans les situations suivantes :

  • Le processus n’a qu’un seul thread.

  • Le processus a plusieurs threads, mais un seul thread appelle les fonctions de tas pour un tas spécifique.

  • Le processus a plusieurs threads et l’application fournit son propre mécanisme d’exclusion mutuelle à un tas spécifique.

Note

Pour vous protéger contre une violation d’accès, utilisez la gestion des exceptions structurées pour protéger tout code qui écrit ou lit à partir d’un tas. Pour plus d’informations sur la gestion des exceptions structurées avec les accès en mémoire, consultez Gestion des exceptions**.

Exigences

Exigence Valeur
client minimum pris en charge Windows XP
plateforme cible Universel
d’en-tête ntifs.h (include Ntifs.h)
bibliothèque Ntoskrnl.lib
DLL NtosKrnl.exe (mode noyau) ; Ntdll.dll (mode utilisateur)
IRQL < DISPATCH_LEVEL

Voir aussi

RtlAllocateHeap

RtlDestroyHeap

RtlFreeHeap